<template>
  <div class="mobile-refund-task">
    <!-- 顶部导航栏 -->
    <div class="mobile-header">
      <div class="header-content">
        <h1 class="header-title">
          <i class="bi bi-list-task"></i>
          退款任务管理
        </h1>
        <div class="header-actions">
          <button class="btn btn-sm btn-outline-light" @click="refreshData" :disabled="loading">
            <i class="bi bi-arrow-clockwise"></i>
          </button>
          <button class="btn btn-sm btn-outline-light" @click="goBack">
            <i class="bi bi-arrow-left"></i>
          </button>
        </div>
      </div>
    </div>

    <!-- 主要内容区域 -->
    <div class="mobile-content">
      <!-- 创建任务按钮 -->
      <div class="create-task-section">
        <button class="btn btn-primary btn-lg w-100 create-task-btn" @click="openCreateTaskDialog"
          :disabled="loading || !canCreateNewTask">
          <i class="bi bi-plus-circle"></i>
          <span v-if="loading">创建中...</span>
          <span v-else>创建退费任务</span>
        </button>

        <!-- 明细数量限制信息 -->
        <div v-if="taskConfig.ui.showUserTotalLimitTip && userTaskAmount > 0" class="task-limit-info">
          <div class="alert alert-info">
            <i class="bi bi-info-circle"></i>
            联系任务工作量：{{ currentDetailCount }} / {{ userTaskAmount }}
            <span v-if="currentDetailCount >= userTaskAmount" class="text-danger">（已达上限）</span>
          </div>
        </div>

        <!-- 单次创建数量限制提示
        <div v-if="taskConfig.ui.showCountLimitTip && taskConfig.creation.enableCountLimit" class="single-limit-info">
          <div class="alert alert-secondary">
            <i class="bi bi-gear"></i>
            单次创建限制：最多 {{ taskConfig.creation.defaultMaxCount }} 条明细记录
          </div>
        </div> -->

        <!-- 倒计时显示 -->
        <div v-if="taskConfig.ui.showCountdown" class="countdown-section">
          <div class="countdown-card">
            <div class="countdown-header">
              <i class="bi bi-clock"></i>
              <span class="countdown-title">任务倒计时</span>
            </div>
            <div class="countdown-content">
              <div class="countdown-display">
                <div class="countdown-item">
                  <span class="countdown-number">{{ countdownData.days }}</span>
                  <span class="countdown-label">天</span>
                </div>
                <div class="countdown-separator">:</div>
                <div class="countdown-item">
                  <span class="countdown-number">{{ countdownData.hours }}</span>
                  <span class="countdown-label">时</span>
                </div>
                <div class="countdown-separator">:</div>
                <div class="countdown-item">
                  <span class="countdown-number">{{ countdownData.minutes }}</span>
                  <span class="countdown-label">分</span>
                </div>
                <div class="countdown-separator">:</div>
                <div class="countdown-item">
                  <span class="countdown-number">{{ countdownData.seconds }}</span>
                  <span class="countdown-label">秒</span>
                </div>
              </div>
              <div class="countdown-info">
                <span class="countdown-text">任务起始时间</span>
                <span class="countdown-deadline">{{ formatStartTime }} - {{ formatDeadlineDate }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 创建任务提示 -->
        <div v-if="!canCreateNewTask && masterData.length > 0" class="create-tip">
          <!-- <div class="alert alert-warning">
            <i class="bi bi-exclamation-triangle"></i>
            <span v-if="taskConfig.creation.enableUserTotalLimit && userTaskAmount > 0 && currentDetailCount >= userTaskAmount">
              您的已完成任务明细数已达到上限 {{ userTaskAmount }} 条，无法创建新任务
            </span>
            <span v-else>
              请完成当前任务中所有患者的联系工作后，再创建新的退费任务
            </span>
          </div> -->
        </div>

        <!-- 坐席账号统计信息 -->
        <div class="agent-stats-section">
          <div class="agent-stats-toggle" @click="toggleAgentStats">
            <div class="toggle-content">
              <i class="bi bi-headset"></i>
              <span class="toggle-text">坐席状态(每次申请使用3小时,15分钟不操作自动取消),点击🔻任务卡片自动申请!</span>
              <div class="quick-stats">
                <span class="stat-badge available">{{ agentAccountStats.availableAccounts }}</span>
                <span class="stat-badge in-use">{{ agentAccountStats.inUseAccounts }}</span>
              </div>
            </div>
            <i :class="showAgentStats ? 'bi bi-chevron-up' : 'bi bi-chevron-down'" class="toggle-icon"></i>
          </div>

          <div v-show="showAgentStats" class="agent-stats-content">
            <div v-if="agentStatsLoading" class="stats-loading">
              <div class="spinner-small"></div>
              <span>加载中...</span>
            </div>
            <div v-else class="stats-grid">
              <div class="stat-card available">
                <div class="stat-icon">
                  <i class="bi bi-check-circle"></i>
                </div>
                <div class="stat-info">
                  <div class="stat-number">{{ agentAccountStats.availableAccounts }}</div>
                  <div class="stat-label">可申请</div>
                </div>
              </div>

              <div class="stat-card in-use">
                <div class="stat-icon">
                  <i class="bi bi-person-check"></i>
                </div>
                <div class="stat-info">
                  <div class="stat-number">{{ agentAccountStats.inUseAccounts }}</div>
                  <div class="stat-label">使用中</div>
                </div>
              </div>

              <div class="stat-card pending">
                <div class="stat-icon">
                  <i class="bi bi-clock"></i>
                </div>
                <div class="stat-info">
                  <div class="stat-number">{{ agentAccountStats.pendingAccounts }}</div>
                  <div class="stat-label">申请中</div>
                </div>
              </div>

              <div class="stat-card total">
                <div class="stat-icon">
                  <i class="bi bi-collection"></i>
                </div>
                <div class="stat-info">
                  <div class="stat-number">{{ agentAccountStats.totalAccounts }}</div>
                  <div class="stat-label">总数</div>
                </div>
              </div>
            </div>

            <div v-if="!agentStatsLoading && agentAccountStats.statisticsTime" class="stats-footer">
              <div class="update-time">
                <i class="bi bi-clock-history"></i>
                更新时间: {{ formatDateTime(agentAccountStats.statisticsTime) }}
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 任务列表 -->
      <div class="task-list" v-if="masterData.length > 0">
        <div v-for="item in masterData" :key="item.id" class="task-card" @click="showDetails(item.id)">
          <!-- 任务头部信息 -->
          <div class="task-header">
            <div class="task-id">
              <i class="bi bi-hash"></i>
              任务 {{ item.id }}
            </div>
            <div class="task-date">
              {{ formatDateTime(item.inputDate) }}
            </div>
          </div>

          <!-- 进度信息 -->
          <div class="task-progress">
            <div class="progress-info">
              <span class="progress-text">联系进度</span>
              <span class="progress-numbers">
                {{ item.contactedCount || 0 }} / {{ item.accountCount || 0 }}
              </span>
            </div>
            <div class="progress-bar-container">
              <div class="progress-bar-fill" :class="getProgressBarClass(item.contactedCount, item.accountCount)"
                :style="{ width: getProgressPercentage(item.contactedCount, item.accountCount) + '%' }"></div>
            </div>
            <div class="progress-percentage">
              {{ getProgressPercentage(item.contactedCount, item.accountCount) }}%
            </div>
          </div>

          <!-- 统计信息 -->
          <div class="task-stats">
            <div class="stat-item">
              <div class="stat-label">总金额</div>
              <div class="stat-value amount">{{ formatCurrency(item.accountSumBalance) }}</div>
            </div>
            <div class="stat-item">
              <div class="stat-label">总记录</div>
              <div class="stat-value">{{ item.accountCount }}</div>
            </div>
          </div>

          <!-- 备注 -->
          <div v-if="item.notes" class="task-notes">
            <i class="bi bi-sticky"></i>
            {{ item.notes }}
          </div>
        </div>
      </div>

      <!-- 无数据提示 -->
      <div class="empty-state" v-if="masterData.length === 0 && !loading">
        <div class="empty-icon">
          <i class="bi bi-inbox"></i>
        </div>
        <div class="empty-title">暂无退费任务</div>
        <div class="empty-subtitle">点击上方按钮创建新的退费任务</div>
      </div>

      <!-- 加载状态 -->
      <div class="loading-state" v-if="loading">
        <div class="loading-spinner">
          <div class="spinner"></div>
        </div>
        <div class="loading-text">{{ loadingText }}</div>
      </div>
    </div>

    <!-- 详情弹窗 -->
    <div class="mobile-modal" :class="{ 'show': showDetailDialog }" @click="closeDetailDialog">
      <div class="modal-content" @click.stop>
        <!-- 详情头部 -->
        <div class="modal-header">
          <h3 class="modal-title">
            <i class="bi bi-list-ul"></i>
            任务详情 #{{ selectedMasterId }}
          </h3>
          <button class="modal-close" @click="closeDetailDialog">
            <i class="bi bi-x-lg"></i>
          </button>
        </div>

        <!-- 详情内容 -->
        <div class="modal-body">
          <div v-if="detailLoading" class="detail-loading">
            <div class="spinner"></div>
            <div>加载详情中...</div>
          </div>

          <div v-else-if="detailData.length > 0" class="detail-content">
            <!-- 患者列表 -->
            <div class="patient-list">
              <div v-for="detail in sortedDetailData" :key="detail.id" class="patient-card" :class="{
                'uncontacted': (detail.contactCount || 0) === 0
              }" @click="showContactRecord(detail)">
                <!-- 患者信息区域 -->
                <div class="patient-info">
                  <!-- 患者基本信息 -->
                  <div class="patient-header">
                    <div class="patient-name">
                      <i class="bi bi-person-fill"></i>
                      {{ detail.patName || '-' }}
                    </div>
                    <div class="patient-contact-count">
                      <span :class="getContactCountClass(detail.contactCount)">
                        {{ detail.contactCount || 0 }}次
                      </span>
                    </div>
                  </div>

                  <!-- 患者详细信息 -->
                  <div class="patient-details">
                    <div class="detail-row">
                      <span class="detail-label">性别:</span>
                      <span class="detail-value">
                        {{ detail.sex || '-' }}
                        <span v-if="calculateAge(detail.idNumber)" class="age-info"> {{ calculateAge(detail.idNumber)
                        }}</span>
                      </span>
                    </div>
                    <div class="detail-row">
                      <span class="detail-label">身份证:</span>
                      <span class="detail-value">{{ maskIdNumber(detail.idNumber) }}</span>
                    </div>
                    <div class="detail-row">
                      <span class="detail-label">电话:</span>
                      <span class="detail-value phone">
                        <i class="bi bi-telephone"></i>
                        {{ maskPhoneNumber(detail.phoneNumber) }}
                      </span>
                    </div>
                    <div class="detail-row">
                      <span class="detail-label">余额:</span>
                      <span class="detail-value amount">{{ formatCurrency(detail.balance) }}</span>
                    </div>
                  </div>

                  <!-- 联系状态 -->
                  <div class="contact-status">
                    <span v-if="detail.notes1" class="status-contacted">
                      <i class="bi bi-check-circle"></i>
                      {{ detail.notes1 }}
                    </span>
                    <span v-else class="status-uncontacted">
                      <i class="bi bi-dash-circle"></i>
                      未联系
                    </span>
                  </div>

                  <!-- 操作指示 -->
                  <!-- <div class="patient-action">
                    <i class="bi bi-chevron-right"></i>
                  </div> -->
                </div>
              </div>
            </div>
          </div>

          <div v-else class="detail-empty">
            <i class="bi bi-exclamation-triangle"></i>
            该任务暂无详情数据
          </div>
        </div>
      </div>
    </div>

    <!-- 联系记录弹窗 -->
    <div class="mobile-modal contact-modal" :class="{ 'show': showContactDialog }" @click="closeContactDialog">
      <div class="modal-content" @click.stop>
        <!-- 联系记录头部 -->
        <div class="modal-header">
          <div class="header-left">
            <div class="title-navigation-row">
              <h3 class="modal-title">
                <i class="bi bi-person-lines-fill"></i>
                {{ selectedContactDetail?.patName }}
              </h3>
              <!-- 导航按钮组 - 与姓名同行 -->
              <div class="header-navigation">
                <button class="btn btn-outline-secondary btn-xs nav-btn-header" :disabled="currentContactIndex <= 0"
                  @click="prevContactRecord" title="上一条联系记录">
                  <i class="bi bi-chevron-left"></i>
                </button>
                <span class="nav-info-header">
                  {{ currentContactIndex + 1 }} / {{ sortedDetailData.length }}
                </span>
                <button class="btn btn-outline-secondary btn-xs nav-btn-header"
                  :disabled="currentContactIndex >= sortedDetailData.length - 1" @click="nextContactRecord"
                  title="下一条联系记录">
                  <i class="bi bi-chevron-right"></i>
                </button>
              </div>
            </div>
          </div>
          <div class="header-right">
            <button class="modal-close" @click="confirmCloseContactDialog">
              <i class="bi bi-x-lg"></i>
            </button>
          </div>
        </div>

        <!-- 联系记录内容 -->
        <div class="modal-body" v-if="selectedContactDetail">
          <!-- 固定信息区域 - 始终可见 -->
          <div class="fixed-info-section">
            <!-- 患者电话 - 核心信息 -->
            <div class="core-info-card">
              <div class="patient-phone-card">
                <div class="phone-icon">
                  <i class="bi bi-telephone-fill"></i>
                </div>
                <div class="phone-info">
                  <div class="phone-label">{{ selectedContactDetail.patName }}电话</div>
                  <div class="phone-number">
                    {{ formatPhoneNumber(selectedContactDetail.phoneNumber) || '暂无电话' }}
                  </div>
                </div>
                <a v-if="selectedContactDetail.phoneNumber && patientBalance > 0"
                  @click="makePhoneCall(selectedContactDetail.phoneNumber, selectedContactDetail.patName, 'patient')"
                  class="phone-action-btn" title="拨打患者电话">
                  <i class="bi bi-telephone-outbound"></i>
                </a>
                <span v-else-if="selectedContactDetail.phoneNumber && patientBalance <= 0"
                  class="phone-action-btn disabled" title="患者已退款，无需联系">
                  <i class="bi bi-telephone-x"></i>
                </span>
              </div>
            </div>

            <!-- 核心基本信息 - 紧凑显示 -->
            <div class="core-basic-info">
              <div class="core-info-grid">
                <div class="core-info-item">
                  <span class="core-label">性别</span>
                  <span class="core-value">
                    {{ selectedContactDetail.sex || '-' }}
                    <span v-if="calculateAge(selectedContactDetail.idNumber)" class="age-info"> {{
                      calculateAge(selectedContactDetail.idNumber) }}</span>
                  </span>
                </div>
                <div class="core-info-item">
                  <span class="core-label">身份证</span>
                  <span class="core-value">{{ maskIdNumber(selectedContactDetail.idNumber) }}</span>
                </div>
              </div>
            </div>

            <!-- HIS余额 - 核心信息 -->
            <div class="core-his-balance">
              <div class="balance-header">
                <div class="balance-title-section">
                  <i class="bi bi-wallet2"></i>
                  <span class="balance-title">HIS当前余额</span>
                </div>
                <button 
                  class="refund-query-btn"
                  @click="handleRefundMasterQuery"
                  title="查询退款申请"
                >
                  <i class="bi bi-arrow-clockwise"></i>
                  查询退款申请
                </button>
              </div>
              <div class="balance-content">
                <span v-if="patientBalanceLoading" class="loading">
                  <i class="bi bi-hourglass-split"></i> 查询中...
                </span>
                <span v-else-if="patientBalanceError" class="error">
                  <i class="bi bi-exclamation-triangle"></i> {{ patientBalanceError }}
                </span>
                <span v-else class="amount" :class="patientBalance > 0 ? 'positive' : 'zero'">
                  ¥{{ (patientBalance || 0).toFixed(2) }}
                </span>
              </div>
            </div>
          </div>

          <!-- 可滚动内容区域 -->
          <div class="scrollable-content">
            <!-- 详细信息折叠卡片 -->
            <div class="collapsible-card">
              <div class="card-header" @click="toggleDetailInfoExpanded">
                <div class="header-content">
                  <i class="bi bi-person-lines-fill"></i>
                  <span>详细信息(点开查阅患者联系人/亲属电话)</span>
                </div>
                <i :class="detailInfoExpanded ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
              </div>

              <div v-show="detailInfoExpanded" class="card-content">
                <div class="detail-info-grid">
                  <!-- 联系人信息 -->
                  <div v-if="selectedContactDetail.nextOfKin" class="detail-info-row">
                    <span class="detail-label">联系人:</span>
                    <span class="detail-value">{{ selectedContactDetail.nextOfKin }}</span>
                  </div>

                  <!-- 联系人电话 -->
                  <div v-if="selectedContactDetail.nextOfKinPhone" class="detail-info-row">
                    <span class="detail-label">联系人电话:</span>
                    <span class="detail-value phone">
                      <i class="bi bi-telephone"></i>
                      <span>{{ formatPhoneNumber(selectedContactDetail.nextOfKinPhone) }}</span>
                      <a v-if="patientBalance > 0"
                        @click="makePhoneCall(selectedContactDetail.nextOfKinPhone, selectedContactDetail.nextOfKin, 'contact')"
                        class="copy-btn-small" title="拨打联系人电话">
                        <i class="bi bi-telephone-fill"></i>
                      </a>
                      <span v-else class="copy-btn-small disabled" title="患者已退款，无需联系">
                        <i class="bi bi-telephone-x"></i>
                      </span>
                    </span>
                  </div>

                  <!-- 监护人信息 -->
                  <div v-if="selectedContactDetail.guardianName" class="detail-info-row">
                    <span class="detail-label">监护人:</span>
                    <span class="detail-value">{{ selectedContactDetail.guardianName }}</span>
                  </div>

                  <div v-if="selectedContactDetail.guardianIdcode" class="detail-info-row">
                    <span class="detail-label">监护人证件号:</span>
                    <span class="detail-value">{{ maskIdNumber(selectedContactDetail.guardianIdcode) }}</span>
                  </div>

                  <!-- 余额信息 -->
                  <div class="detail-info-row">
                    <span class="detail-label">余额:</span>
                    <span class="detail-value amount">{{ formatCurrency(selectedContactDetail.balance) }}</span>
                  </div>
                </div>
              </div>
            </div>

            <!-- 快速沟通指引折叠卡片 -->
            <div class="collapsible-card">
              <div class="card-header" @click="toggleGuideExpanded">
                <div class="header-content">
                  <i class="bi bi-chat-dots"></i>
                  <span>沟通指引</span>
                </div>
                <i :class="guideExpanded ? 'bi bi-chevron-up' : 'bi bi-chevron-down'"></i>
              </div>

              <div v-show="guideExpanded" class="card-content">
                <!-- 沟通术语 -->
                <div class="guide-section">
                  <h6><i class="bi bi-chat-text text-primary"></i> 沟通术语</h6>
                  <div class="terms-list">
                    <div v-for="(term, index) in communicationGuide.terms" :key="index" class="term-item">
                      <div class="term-title">{{ term.title }}：</div>
                      <div class="term-content">{{ term.content }}</div>
                    </div>
                  </div>
                </div>

                <!-- 常用话术 -->
                <div class="guide-section">
                  <h6><i class="bi bi-list-check text-success"></i> 常用话术</h6>
                  <div class="scripts-list">
                    <div v-for="(script, index) in communicationGuide.scripts" :key="index" class="script-category">
                      <div class="category-title">{{ script.category }}</div>
                      <div class="script-items">
                        <div v-for="(item, itemIndex) in script.items" :key="itemIndex" class="script-item"
                          @click="copyToClipboard(item)">
                          <i class="bi bi-chat-text"></i>
                          {{ item }}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 注意事项 -->
                <div class="guide-section">
                  <h6><i class="bi bi-exclamation-triangle text-warning"></i> 注意事项</h6>
                  <div class="note-list">
                    <div v-for="(note, index) in communicationGuide.notes" :key="index" class="note-item">
                      <i class="bi bi-check-circle"></i>
                      {{ note }}
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 联系记录表单 -->
            <div class="contact-records-section">
              <div class="section-header">
                <h6>
                  <i class="bi bi-clock-history"></i>
                  联系记录
                </h6>
              </div>

              <!-- 联系记录列表 -->
              <div class="contact-records-list">
                <div v-for="record in getContactRecords(selectedContactDetail)" :key="record.index"
                  class="contact-record-item"
                  :class="{ 'saved': isContactRecordSaved(record.index), 'disabled': !canEditContactRecord(record.index) }">
                  <div class="record-header">
                    <span class="record-number">第{{ record.index }}次联系</span>
                    <span v-if="record.contactTime" class="record-time">
                      {{ formatDateTime(record.contactTime) }}
                    </span>
                  </div>

                  <!-- 联系结果选择 -->
                  <div class="form-group">
                    <label class="form-label">联系结果</label>

                    <!-- 已保存的结果 - 不可编辑 -->
                    <div v-if="isContactRecordSaved(record.index)" class="form-value saved">
                      <div class="saved-result">
                        <i class="bi bi-check-circle-fill"></i>
                        <span class="result-text">{{ record.notes }}</span>
                        <span class="saved-badge">已保存</span>
                      </div>
                    </div>

                    <!-- 可编辑的选择器 - 下拉菜单形式 -->
                    <div v-else-if="canEditContactRecord(record.index)" class="contact-result-selector">
                      <div class="result-select-container">
                        <select class="form-select contact-result-select"
                          v-model="selectedContactDetail[`notes${record.index}`]"
                          @change="onContactResultSelect(record.index)">
                          <option value="" disabled>请选择联系结果</option>
                          <option v-for="option in contactResultOptions" :key="option.id" :value="option.itemName">
                            {{ option.itemName }}
                          </option>
                        </select>

                        <!-- 保存按钮 - 紧跟在下拉菜单后面 -->
                        <button v-if="hasContactResultForRecord(record.index)"
                          class="btn btn-success btn-sm save-btn-inline" :disabled="!canSaveContactRecord(record.index)"
                          @click="saveContactRecordForIndex(record.index)">
                          <i class="bi bi-check"></i> 保存
                        </button>
                      </div>
                    </div>

                    <!-- 不可编辑状态 -->
                    <div v-else class="form-value disabled">
                      <i class="bi bi-lock-fill"></i>
                      <span>需要完成第{{ record.index - 1 }}次联系后才能填写</span>
                    </div>
                  </div>

                </div>
              </div>

              <!-- 无联系记录提示 -->
              <div v-if="getContactRecords(selectedContactDetail).length === 0" class="no-records">
                <i class="bi bi-inbox"></i>
                暂无联系记录
              </div>

              <!-- 跳转下一条记录提示 -->
              <div v-if="showNextRecordPrompt" class="next-record-prompt">
                <div class="prompt-content">
                  <div class="prompt-header">
                    <i class="bi bi-arrow-right-circle-fill text-primary"></i>
                    <span class="prompt-title">继续联系</span>
                  </div>
                  <div class="prompt-message">
                    是否跳转到下一条未联系的记录？
                  </div>
                  <div class="prompt-actions">
                    <button class="btn btn-primary btn-sm" @click="goToNextUncontactedRecord">
                      <i class="bi bi-arrow-right"></i> 跳转下一条
                    </button>
                    <button class="btn btn-outline-secondary btn-sm" @click="dismissNextRecordPrompt">
                      继续当前
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 创建任务弹窗 -->
    <div class="mobile-modal create-task-modal" :class="{ 'show': showCreateTaskDialog }"
      @click="closeCreateTaskDialog">
      <div class="modal-content" @click.stop>
        <!-- 弹窗头部 -->
        <div class="modal-header">
          <h3 class="modal-title">
            <i class="bi bi-plus-circle"></i>
            创建退费任务
          </h3>
          <button class="btn-close" @click="closeCreateTaskDialog">
            <i class="bi bi-x"></i>
          </button>
        </div>

        <!-- 弹窗内容 -->
        <div class="modal-body">
          <div class="create-task-form">
            <!-- 明细数量选择 -->
            <div class="form-group">
              <label class="form-label">
                <i class="bi bi-list-ol"></i>
                选择创建明细数量
              </label>
              <div class="quantity-selector">
                <div class="quantity-display">
                  <span class="quantity-value">{{ selectedDetailCount }}</span>
                  <span class="quantity-unit">条明细记录</span>
                </div>
                <div class="quantity-slider">
                  <input type="range" v-model="selectedDetailCount" :min="taskConfig.creation.minCount"
                    :max="maxAllowedDetailCount" :step="1" class="slider" />
                  <div class="slider-labels">
                    <span>{{ taskConfig.creation.minCount }}</span>
                    <span>{{ maxAllowedDetailCount }}</span>
                  </div>
                </div>
              </div>
            </div>

            <!-- 限制提示信息 -->
            <div class="limit-info">
              <div class="alert alert-info">
                <i class="bi bi-info-circle"></i>
                <div>
                  <div>已完成任务明细数：{{ currentDetailCount }} / {{ userTaskAmount || '无限制' }}</div>
                  <div v-if="userTaskAmount > 0">剩余可创建：{{ Math.max(0, userTaskAmount - currentDetailCount) }} 条</div>
                  <div>本次创建数量：{{ selectedDetailCount }} 条</div>
                  <div class="text-muted small">注：实际创建数量取决于HIS数据库中的可用数据</div>
                </div>
              </div>

              <!-- 超限警告 -->
              <div v-if="userTaskAmount > 0 && currentDetailCount >= userTaskAmount" class="alert alert-warning">
                <i class="bi bi-exclamation-triangle"></i>
                您的已完成任务明细数已达到上限，无法创建新任务！
              </div>
              <div v-else-if="userTaskAmount > 0 && selectedDetailCount > 0" class="alert alert-info">
                <i class="bi bi-info-circle"></i>
                提示：实际创建的明细数量将根据HIS数据库中的可用数据确定，可能少于选择的数量。
              </div>
            </div>
          </div>
        </div>

        <!-- 弹窗底部 -->
        <div class="modal-footer">
          <button class="btn btn-outline-secondary" @click="closeCreateTaskDialog">
            <i class="bi bi-x-circle"></i>
            取消
          </button>
          <button class="btn btn-primary" @click="confirmCreateTask" :disabled="createTaskLoading || !canCreateNewTask">
            <i class="bi bi-check-circle"></i>
            <span v-if="createTaskLoading">创建中...</span>
            <span v-else>确认创建</span>
          </button>
        </div>
      </div>
    </div>

    <!-- 自定义确认对话框 -->
    <div class="mobile-modal confirm-dialog" :class="{ 'show': showConfirmDialog }" @click="handleConfirmDialogCancel">
      <div class="modal-content confirm-content" @click.stop>
        <!-- 确认对话框头部 -->
        <div class="modal-header confirm-header">
          <h3 class="modal-title confirm-title">
            <i class="bi bi-question-circle"></i>
            {{ confirmDialogData.title }}
          </h3>
        </div>

        <!-- 确认对话框内容 -->
        <div class="modal-body confirm-body">
          <div class="confirm-message">
            {{ confirmDialogData.message }}
          </div>
        </div>

        <!-- 确认对话框底部 -->
        <div class="modal-footer confirm-footer">
          <button class="btn btn-outline-secondary" @click="handleConfirmDialogCancel">
            {{ confirmDialogData.cancelText }}
          </button>
          <button class="btn btn-primary" @click="handleConfirmDialogConfirm">
            {{ confirmDialogData.confirmText }}
          </button>
        </div>
      </div>
    </div>

    <!-- 自定义输入对话框 -->
    <div class="mobile-modal input-dialog" :class="{ 'show': showInputDialog }" @click="handleInputDialogCancel">
      <div class="modal-content input-content" @click.stop>
        <!-- 输入对话框头部 -->
        <div class="modal-header input-header">
          <h3 class="modal-title input-title">
            <i class="bi bi-pencil-square"></i>
            {{ inputDialogData.title }}
          </h3>
        </div>

        <!-- 输入对话框内容 -->
        <div class="modal-body input-body">
          <div class="input-message" v-if="inputDialogData.message">
            {{ inputDialogData.message }}
          </div>
          <div class="input-field">
            <input type="text" class="form-control input-control" v-model="inputDialogData.inputValue"
              :placeholder="inputDialogData.placeholder" @keyup.enter="handleInputDialogConfirm" ref="inputField" />
          </div>
        </div>

        <!-- 输入对话框底部 -->
        <div class="modal-footer input-footer">
          <button class="btn btn-outline-secondary" @click="handleInputDialogCancel">
            {{ inputDialogData.cancelText }}
          </button>
          <button class="btn btn-primary" @click="handleInputDialogConfirm">
            {{ inputDialogData.confirmText }}
          </button>
        </div>
      </div>
    </div>
  </div>

  <!-- 退费申请查询结果弹窗 -->
  <div class="mobile-modal refund-query-modal" :class="{ 'show': refundQueryDialog }" @click="closeRefundQueryDialog">
    <div class="modal-content" @click.stop>
      <!-- 弹窗头部 -->
      <div class="modal-header">
        <h3 class="modal-title">
          <i class="bi bi-receipt"></i>
          退费申请查询结果
        </h3>
        <button class="modal-close" @click="closeRefundQueryDialog">
          <i class="bi bi-x-lg"></i>
        </button>
      </div>

      <!-- 弹窗内容 -->
      <div class="modal-body">
        <!-- 加载状态 -->
        <div v-if="refundQueryLoading" class="detail-loading">
          <div class="spinner"></div>
          <div>查询退费申请中...</div>
        </div>

        <!-- 无数据状态 -->
        <div v-else-if="refundQueryData.length === 0" class="empty-state">
          <div class="empty-icon">
            <i class="bi bi-inbox"></i>
          </div>
          <div class="empty-title">未查询到退费申请</div>
          <div class="empty-subtitle">当前患者未申请线上退款</div>
          <div class="refund-dialog-footer">
            <button class="btn btn-secondary" @click="closeRefundQueryDialog">
              <i class="bi bi-x-circle"></i>
              关闭
            </button>
          </div>
        </div>

        <!-- 有数据状态 -->
        <div v-else class="refund-list">
          <div class="refund-summary">
            <div class="summary-item">
              <i class="bi bi-file-text"></i>
              <span>共查询到 {{ refundQueryData.length }} 条记录</span>
            </div>
          </div>

          <div class="refund-items">
            <div 
              v-for="(refund, index) in refundQueryData" 
              :key="index" 
              class="refund-item-card"
            >
              <div class="refund-header">
                <div class="refund-date">
                  <i class="bi bi-calendar3"></i>
                  {{ formatDateTime(refund.inputDate) }}
                </div>
                <div class="refund-status" :class="formatAuditStatus(refund.auditResult).class">
                  <i class="bi bi-circle-fill"></i>
                  {{ formatAuditStatus(refund.auditResult).text }}
                </div>
              </div>

              <div class="refund-amount">
                <div class="amount-label">退款金额</div>
                <div class="amount-value">¥{{ (refund.refundBalance || 0).toFixed(2) }}</div>
              </div>

              <div class="refund-description">
                {{ refund.auditComment }}
              </div>
            </div>
          </div>
          
          <!-- 底部关闭按钮 -->
          <div class="refund-dialog-footer">
            <button class="btn btn-secondary" @click="closeRefundQueryDialog">
              <i class="bi bi-x-circle"></i>
              关闭
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import api from '@/utils/api'
import communicationGuide from '@/config/communicationGuide'
import { taskConfig, validateSingleTaskCount, validateUserTotalTaskCount } from '@/config/taskConfig'
import CryptoJS from 'crypto-js'

// 响应式数据
const loading = ref(false)
const loadingText = ref('加载中...')
const masterData = ref([])
const detailData = ref([])
const detailLoading = ref(false)
const showDetailDialog = ref(false)
const showContactDialog = ref(false)
const selectedMasterId = ref(null)
const selectedContactDetail = ref(null)
const currentDetailIndex = ref(0)
const currentContactIndex = ref(0) // 当前联系记录索引

// 自定义确认对话框
const showConfirmDialog = ref(false)
const confirmDialogData = ref({
  title: '',
  message: '',
  confirmText: '确定',
  cancelText: '取消',
  onConfirm: null,
  onCancel: null
})

// 自定义输入对话框
const showInputDialog = ref(false)
const inputDialogData = ref({
  title: '',
  message: '',
  placeholder: '',
  inputValue: '',
  confirmText: '确定',
  cancelText: '取消',
  onConfirm: null,
  onCancel: null,
  validator: null
})
const patientBalanceLoading = ref(false)
const patientBalanceError = ref('')
const patientBalance = ref(0)
const guideExpanded = ref(false)
const detailInfoExpanded = ref(false) // 详细信息折叠状态
const latestTaskDetails = ref([])

// 任务数量限制相关状态
const userTaskAmount = ref(0) // 用户明细总数量限制
const currentDetailCount = ref(0) // 当前已创建的明细记录总数
const taskLimitLoading = ref(false) // 任务限制检查加载状态

// 创建任务弹窗相关状态
const showCreateTaskDialog = ref(false) // 显示创建任务弹窗
const selectedDetailCount = ref(0) // 选择的明细数量，默认0条
const createTaskLoading = ref(false) // 创建任务加载状态

// 网络和错误处理相关状态
const isOffline = ref(false)
const retryCount = ref(0)

// 倒计时相关状态
const countdownData = ref({
  days: 0,
  hours: 0,
  minutes: 0,
  seconds: 0
})
const countdownTimer = ref(null)
const maxRetries = 3
const lastUpdateTime = ref(null)

// 坐席账号统计相关状态
const agentAccountStats = ref({
  totalAccounts: 0,
  inUseAccounts: 0,
  availableAccounts: 0,
  pendingAccounts: 0,
  inactiveAccounts: 0,
  expiredAccounts: 0,
  lockTimeoutAccounts: 0,
  statisticsTime: null,
  inactiveMinutes: 30,
  usageDurationMinutes: 120
})
const agentStatsLoading = ref(false)
const showAgentStats = ref(false) // 控制坐席统计信息的显示

// 路由和认证
const router = useRouter()
const authStore = useAuthStore()

// 计算属性
const canCreateNewTask = computed(() => {
  // 检查任务配置是否启用限制
  if (taskConfig.creation.enableCountLimit || taskConfig.creation.enableUserTotalLimit) {
    // 检查用户总明细数限制
    if (taskConfig.creation.enableUserTotalLimit && userTaskAmount.value > 0) {
      if (currentDetailCount.value >= userTaskAmount.value) {
        return false
      }
    }
  }

  // 如果没有任何任务，可以创建（第一次创建）
  if (masterData.value.length === 0) {
    return true
  }

  // 如果最新任务的详情数据为空，暂时不允许创建
  if (latestTaskDetails.value.length === 0) {
    return false
  }

  // 检查最新任务的所有明细记录是否都有联系次数大于0
  return latestTaskDetails.value.every(detail => (detail.contactCount || 0) > 0)
})

const sortedDetailData = computed(() => {
  return [...detailData.value].sort((a, b) => {
    const aContacted = (a.contactCount || 0) > 0
    const bContacted = (b.contactCount || 0) > 0
    if (aContacted === bContacted) return 0
    return aContacted ? 1 : -1
  })
})

const uncontactedCount = computed(() => {
  return detailData.value.filter(item => (item.contactCount || 0) === 0).length
})

// 倒计时相关计算属性
const formatDeadlineDate = computed(() => {
  const startDate = new Date(taskConfig.countdown.startDate)
  const deadlineDate = new Date(startDate.getTime() + taskConfig.countdown.daysLimit * 24 * 60 * 60 * 1000)
  return deadlineDate.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  })
})

const formatStartTime = computed(() => {
  const startDate = new Date(taskConfig.countdown.startDate)
  return startDate.toLocaleDateString('zh-CN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  })
})

const isCountdownExpired = computed(() => {
  const now = new Date()
  const startDate = new Date(taskConfig.countdown.startDate)
  const deadlineDate = new Date(startDate.getTime() + taskConfig.countdown.daysLimit * 24 * 60 * 60 * 1000)
  return now > deadlineDate
})

const contactedCount = computed(() => {
  return detailData.value.filter(item => (item.contactCount || 0) > 0).length
})

// Calculate the maximum allowed detail count for the slider
const maxAllowedDetailCount = computed(() => {
  // If user total limit is enabled and we have a limit
  if (taskConfig.creation.enableUserTotalLimit && userTaskAmount.value > 0) {
    // Calculate remaining detail count the user can create
    const remainingCount = userTaskAmount.value - currentDetailCount.value
    // Return the smaller value between remaining count and config max count
    return Math.min(remainingCount, taskConfig.creation.defaultMaxCount)
  }
  // If no user limit, use the config default max count
  return taskConfig.creation.defaultMaxCount
})

// 联系记录相关状态
const hasContactResultChanges = ref(false)
const hasUnsavedChanges = ref(false)
const originalContactData = ref({})
const contactResultOptions = ref([]) // 联系结果选项

// 跳转下一条记录提示相关状态
const showNextRecordPrompt = ref(false)
const nextRecordPromptTimer = ref(null)

// 方法
const formatDateTime = (dateStr) => {
  if (!dateStr) return '-'
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

// 格式化审核状态
const formatAuditStatus = (statusCode) => {
  const statusMap = {
    0: { text: '待审核', class: 'pending' },
    1: { text: '审核通过', class: 'approved' },
    2: { text: '审核拒绝', class: 'rejected' },
    3: { text: '已完成', class: 'completed' }
  }
  return statusMap[statusCode] || { text: '未知状态', class: 'pending' }
}

// 生成时间戳 (yyyyMMddHHmmss)
const generateAccountAuthTimestamp = () => {
  const now = new Date()
  const year = now.getFullYear()
  const month = String(now.getMonth() + 1).padStart(2, '0')
  const day = String(now.getDate()).padStart(2, '0')
  const hours = String(now.getHours()).padStart(2, '0')
  const minutes = String(now.getMinutes()).padStart(2, '0')
  const seconds = String(now.getSeconds()).padStart(2, '0')
  return `${year}${month}${day}${hours}${minutes}${seconds}`
}

const formatCurrency = (amount) => {
  if (!amount) return '¥0.00'
  return `¥${parseFloat(amount).toFixed(2)}`
}

const getProgressPercentage = (contacted, total) => {
  if (!total || total === 0) return 0
  return Math.round((contacted || 0) / total * 100)
}

const getProgressBarClass = (contacted, total) => {
  const percentage = getProgressPercentage(contacted, total)
  if (percentage === 100) return 'complete'
  if (percentage >= 50) return 'good'
  if (percentage > 0) return 'started'
  return 'none'
}

const getContactCountClass = (count) => {
  if (!count || count === 0) return 'badge bg-warning'
  return 'badge bg-success'
}

const maskIdNumber = (idNumber) => {
  if (!idNumber) return '-'
  if (idNumber.length <= 8) return idNumber
  return idNumber.substring(0, 4) + '****' + idNumber.substring(idNumber.length - 4)
}

const maskPhoneNumber = (phone) => {
  if (!phone) return '-'
  if (phone.length <= 7) return phone
  return phone.substring(0, 3) + '****' + phone.substring(phone.length - 4)
}

const formatPhoneNumber = (phone) => {
  if (!phone) return ''
  return phone.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3')
}

const copyPhoneNumber = async (phone) => {
  try {
    await navigator.clipboard.writeText(phone)
    // 简单的提示
    alert('电话号码已复制')
  } catch (err) {
    console.error('复制失败:', err)
  }
}

const copyToClipboard = async (text) => {
  try {
    await navigator.clipboard.writeText(text)
    alert('已复制到剪贴板')
  } catch (err) {
    console.error('复制失败:', err)
  }
}

// 根据身份证计算年龄
const calculateAge = (idNumber) => {
  if (!idNumber || idNumber.length < 14) return ''

  try {
    // 提取出生日期
    let birthYear, birthMonth, birthDay

    if (idNumber.length === 15) {
      // 15位身份证
      birthYear = parseInt('19' + idNumber.substring(6, 8))
      birthMonth = parseInt(idNumber.substring(8, 10))
      birthDay = parseInt(idNumber.substring(10, 12))
    } else if (idNumber.length === 18) {
      // 18位身份证
      birthYear = parseInt(idNumber.substring(6, 10))
      birthMonth = parseInt(idNumber.substring(10, 12))
      birthDay = parseInt(idNumber.substring(12, 14))
    } else {
      return ''
    }

    // 验证日期有效性
    if (birthYear < 1900 || birthYear > new Date().getFullYear() ||
      birthMonth < 1 || birthMonth > 12 ||
      birthDay < 1 || birthDay > 31) {
      return ''
    }

    // 计算年龄
    const today = new Date()
    const birthDate = new Date(birthYear, birthMonth - 1, birthDay)

    let age = today.getFullYear() - birthYear

    // 检查是否还没到生日
    if (today.getMonth() < birthMonth - 1 ||
      (today.getMonth() === birthMonth - 1 && today.getDate() < birthDay)) {
      age--
    }

    return age >= 0 ? age + '岁' : ''
  } catch (error) {
    return ''
  }
}

const toggleGuideExpanded = () => {
  guideExpanded.value = !guideExpanded.value
}

const toggleDetailInfoExpanded = () => {
  detailInfoExpanded.value = !detailInfoExpanded.value
}

// 网络状态检测
const checkNetworkStatus = () => {
  isOffline.value = !navigator.onLine
}

// 错误重试机制
const retryOperation = async (operation, operationName = '操作') => {
  for (let i = 0; i <= maxRetries; i++) {
    try {
      retryCount.value = i
      const result = await operation()
      retryCount.value = 0
      return result
    } catch (error) {
      console.error(`${operationName}失败 (第${i + 1}次尝试):`, error)

      if (i === maxRetries) {
        retryCount.value = 0
        throw new Error(`${operationName}失败，已重试${maxRetries}次。请检查网络连接后重试。`)
      }

      // 等待递增的时间后重试
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)))
    }
  }
}

// 获取用户任务数量限制
const loadUserTaskAmount = async () => {
  try {
    if (!authStore.isAuthenticated || !authStore.user) {
      console.warn('用户未登录，跳过任务数量限制检查')
      return
    }

    taskLimitLoading.value = true

    const response = await api.post('/api/uumuser/get-task-amount', {
      userName: authStore.user.username
    })

    if (response.data && response.data.success) {
      userTaskAmount.value = response.data.taskAmount || 0
      console.log('用户任务数量限制:', userTaskAmount.value)
    } else {
      console.warn('获取用户任务数量限制失败:', response.data?.message)
      userTaskAmount.value = 0
    }
  } catch (error) {
    console.error('获取用户任务数量限制失败:', error)
    userTaskAmount.value = 0
  } finally {
    taskLimitLoading.value = false
  }
}

// API 调用方法
const loadMasterData = async () => {
  try {
    // 检查用户登录状态
    if (!authStore.isAuthenticated || !authStore.user) {
      alert('用户未登录，请先登录')
      return
    }

    loading.value = true
    loadingText.value = '加载退费任务数据...'

    // 使用重试机制加载数据
    await retryOperation(async () => {
      const response = await api.post('/api/RefundTaskMaster/get-by-username', {
        username: authStore.user.username
      })

      masterData.value = response.data || []
      lastUpdateTime.value = new Date()

      // 更新当前明细数量将在 loadContactStatsForAllTasks 中计算
      // currentDetailCount.value 将在加载详情统计时更新

      // 为每个任务加载联系统计数信息
      if (masterData.value.length > 0) {
        await loadContactStatsForAllTasks()
        await loadLatestTaskDetails()
      } else {
        latestTaskDetails.value = []
      }

      // 获取用户任务数量限制
      await loadUserTaskAmount()
    }, '加载主表数据')

  } catch (error) {
    console.error('加载主表数据失败:', error)
    alert(error.message || '加载数据失败，请重试')
  } finally {
    loading.value = false
  }
}

// 为所有任务加载联系统计数信息
const loadContactStatsForAllTasks = async () => {
  try {
    let totalDetailCount = 0 // 统计所有明细记录总数
    let completedTaskDetailCount = 0 // 统计已完成任务的明细记录总数

    // 并行加载所有任务的详情数据来计算联系统计数
    const promises = masterData.value.map(async (task) => {
      try {
        const response = await api.post('/api/RefundTaskDetail/get-by-master-id', {
          id: task.id
        })

        const details = response.data || []
        // 计算已联系的患者数量（联系次数大于0）
        const contactedCount = details.filter(detail => (detail.contactCount || 0) > 0).length

        // 判断任务是否已完成（所有明细都有联系记录）
        const isTaskCompleted = details.length > 0 && details.every(detail => (detail.contactCount || 0) > 0)

        // 将联系统计数信息添加到任务对象中
        task.contactedCount = contactedCount
        task.isCompleted = isTaskCompleted

        // 累计明细记录总数
        totalDetailCount += details.length

        // 只累计已完成任务的明细记录数（用于创建新任务时的限制检查）
        if (isTaskCompleted) {
          completedTaskDetailCount += details.length
        }

        return task
      } catch (error) {
        console.error(`加载任务 ${task.id} 的详情失败:`, error)
        // 如果加载失败，设置默认值
        task.contactedCount = 0
        task.isCompleted = false
        return task
      }
    })

    await Promise.all(promises)

    // 更新当前已联系的明细记录总数（计算所有任务中已联系的明细数量）
    let totalContactedDetailCount = 0
    masterData.value.forEach(task => {
      totalContactedDetailCount += task.contactedCount || 0
    })
    currentDetailCount.value = totalContactedDetailCount
  } catch (error) {
    console.error('加载联系统计数信息失败:', error)
  }
}

// 优化：直接更新前端联系统计数，避免重复调用接口
const updateContactStatsForTask = (masterId, contactCountChange = 0) => {
  const task = masterData.value.find(t => t.id === masterId)
  if (task) {
    // 如果联系次数增加，则已联系患者数量也增加
    if (contactCountChange > 0) {
      task.contactedCount = (task.contactedCount || 0) + 1
      // 同时更新总的已联系明细数量
      currentDetailCount.value = (currentDetailCount.value || 0) + 1
    }
  }
}

// 加载最新任务的详情数据
const loadLatestTaskDetails = async () => {
  try {
    if (masterData.value.length === 0) {
      latestTaskDetails.value = []
      return
    }

    // 获取最新的任务（按创建时间排序，取第一个）
    const latestTask = masterData.value.reduce((latest, current) => {
      const latestDate = new Date(latest.inputDate)
      const currentDate = new Date(current.inputDate)
      return currentDate > latestDate ? current : latest
    })

    // 加载最新任务的详情数据
    const response = await api.post('/api/RefundTaskDetail/get-by-master-id', {
      id: latestTask.id
    })

    latestTaskDetails.value = response.data || []
  } catch (error) {
    console.error('加载最新任务详情失败:', error)
    latestTaskDetails.value = []
  }
}

// 获取坐席账号统计信息
const loadAgentAccountStats = async () => {
  try {
    agentStatsLoading.value = true

    const response = await api.get('/api/AgentAccount/status')

    if (response.data && response.data.success) {
      agentAccountStats.value = {
        totalAccounts: response.data.data.totalAccounts || 0,
        inUseAccounts: response.data.data.inUseAccounts || 0,
        availableAccounts: response.data.data.availableAccounts || 0,
        pendingAccounts: response.data.data.pendingAccounts || 0,
        inactiveAccounts: response.data.data.inactiveAccounts || 0,
        expiredAccounts: response.data.data.expiredAccounts || 0,
        lockTimeoutAccounts: response.data.data.lockTimeoutAccounts || 0,
        statisticsTime: response.data.data.statisticsTime,
        inactiveMinutes: response.data.data.inactiveMinutes || 30,
        usageDurationMinutes: response.data.data.usageDurationMinutes || 120
      }
    } else {
      console.warn('获取坐席账号统计失败:', response.data?.message)
    }
  } catch (error) {
    console.error('获取坐席账号统计失败:', error)
    // 如果获取失败，保持默认值
  } finally {
    agentStatsLoading.value = false
  }
}

// 切换坐席统计信息显示状态
const toggleAgentStats = () => {
  showAgentStats.value = !showAgentStats.value
  if (showAgentStats.value && !agentStatsLoading.value) {
    loadAgentAccountStats()
  }
}

// 显示创建任务弹窗
const openCreateTaskDialog = async () => {
  // 重置选择的明细数量为默认值，但不能超过允许的最大值
  const defaultCount = Math.max(taskConfig.creation.minCount, Math.min(10, maxAllowedDetailCount.value))
  selectedDetailCount.value = Math.min(defaultCount, maxAllowedDetailCount.value)

  // 显示弹窗
  showCreateTaskDialog.value = true
}

// 关闭创建任务弹窗
const closeCreateTaskDialog = () => {
  showCreateTaskDialog.value = false
  createTaskLoading.value = false
}

// 确认创建任务
const confirmCreateTask = async () => {
  createTaskLoading.value = true

  try {
    // 调用原来的创建任务逻辑，传入选择的明细数量
    await createRefundTaskWithCount(selectedDetailCount.value)

    // 创建成功后关闭弹窗
    closeCreateTaskDialog()
  } catch (error) {
    console.error('创建任务失败:', error)
    createTaskLoading.value = false
  }
}

// 原来的创建任务函数，现在改为内部函数，支持传入明细数量
const createRefundTaskWithCount = async (detailCount = null) => {
  // 检查基本创建条件
  if (!canCreateNewTask.value) {
    // 检查是否是因为明细数量限制
    if (taskConfig.creation.enableUserTotalLimit && userTaskAmount.value > 0) {
      const totalLimitValidation = validateUserTotalTaskCount(currentDetailCount.value, userTaskAmount.value)
      if (!totalLimitValidation.valid) {
        alert(totalLimitValidation.message)
        return
      }
    }

    // 检查是否是因为当前任务未完成
    const uncontactedCount = latestTaskDetails.value.filter(detail => (detail.contactCount || 0) === 0).length
    if (uncontactedCount > 0) {
      alert(taskConfig.messages.currentTaskIncomplete.replace('{uncontactedCount}', uncontactedCount))
      return
    }

    alert('当前无法创建新任务，请检查任务状态')
    return
  }

  // 使用传入的明细数量或预估数量
  let targetDetailCount = detailCount
  if (!targetDetailCount) {
    // 如果没有传入明细数量，则使用预估逻辑（兼容旧的调用方式）
    if (masterData.value.length > 0) {
      // 计算平均任务明细记录数
      const totalDetails = masterData.value.reduce((sum, task) => sum + (task.accountCount || 0), 0)
      targetDetailCount = Math.ceil(totalDetails / masterData.value.length) || 50 // 默认估算50条
    } else {
      targetDetailCount = 100 // 首次创建默认估算100条
    }
  }

  // 验证单次创建明细数量限制
  if (taskConfig.creation.enableCountLimit) {
    const singleCountValidation = validateSingleTaskCount(targetDetailCount)
    if (!singleCountValidation.valid) {
      alert(singleCountValidation.message)
      return
    }
  }

  // 注意：不再在此处检查是否会超出用户明细总数限制
  // 因为实际创建的明细数量可能少于预计数量，具体取决于HIS数据库中的可用数据
  // 用户明细总数限制的检查已在canCreateNewTask计算属性中处理

  try {
    loading.value = true
    loadingText.value = '创建退费任务中...'

    // 构建请求数据
    const requestData = {
      username: authStore.user?.username,
      fullname: authStore.user?.fullName || authStore.user?.username,
      accountCount: 0,
      accountSumBalance: 0
    }

    const response = await api.post(`/api/RefundTaskMaster/create-with-his-data?maxCount=${targetDetailCount}`, requestData)

    // 与Web端保持一致的响应数据处理
    if (response.data && response.data.id) {
      const actualCount = response.data.actualCount || 0
      const successMessage = `任务创建成功！实际创建了 ${actualCount} 条明细记录`
      alert(successMessage)
      // 重新加载数据以更新明细数量计数
      await loadMasterData()
    } else {
      alert(taskConfig.messages.createFailed.replace('{error}', response.data?.message || '未知错误'))
    }
  } catch (error) {
    console.error('创建任务失败:', error)
    alert(taskConfig.messages.createFailed.replace('{error}', error.response?.data?.message || error.message))
  } finally {
    loading.value = false
  }
}

const showDetails = async (masterId) => {
  try {
    // 检查用户坐席权限
    const user = authStore.user
    if (!user?.username) {
      alert('用户信息获取失败，请重新登录')
      return
    }

    // 调用坐席权限检查接口
    const statusResponse = await api.post('/api/AgentAccount/user-status', {
      username: user.username
    })

    if (!statusResponse.data?.success) {
      alert('权限检查失败，请稍后重试')
      return
    }

    const agentStatus = statusResponse.data.data

    // 检查是否有有效的坐席权限
    if (!agentStatus.hasAccount || agentStatus.accountStatus !== 'active') {
      // 若用户无坐席使用权，执行完整的坐席申请和鉴权流程
      await handleAgentAccountProcess(user, masterId)
      return
    }

    // 权限验证通过，继续显示任务详情
    selectedMasterId.value = masterId
    showDetailDialog.value = true

    detailLoading.value = true

    await retryOperation(async () => {
      const response = await api.post('/api/RefundTaskDetail/get-by-master-id', { id: masterId })

      if (response.data) {
        detailData.value = response.data || []
        // 对身份证和电话号码进行脱敏处理
        detailData.value.forEach(item => {
          if (item.idNumber) {
            item.maskedIdNumber = maskIdNumber(item.idNumber)
          }
          if (item.phoneNumber) {
            item.maskedPhoneNumber = maskPhoneNumber(item.phoneNumber)
          }
        })
      } else {
        throw new Error('未获取到数据')
      }
    }, '加载详情')

  } catch (error) {
    console.error('加载详情失败:', error)

    // 如果是权限检查相关的错误，给出更友好的提示
    if (error.response?.status === 401) {
      alert('登录已过期，请重新登录')
      authStore.logout()
      router.push('/login')
      return
    }

    if (error.response?.status === 403) {
      alert('您没有权限执行此操作')
      return
    }

    // 其他错误的通用处理
    const errorMessage = error.response?.data?.message || error.message || '加载详情失败'
    alert('操作失败: ' + errorMessage)
  } finally {
    detailLoading.value = false
  }
}

const showContactRecord = async (detail) => {
  selectedContactDetail.value = detail
  showContactDialog.value = true

  // 设置当前联系记录索引
  const index = sortedDetailData.value.findIndex(item => item.id === detail.id)
  currentContactIndex.value = index !== -1 ? index : 0

  // 保存原始数据用于变更检测
  originalContactData.value = { ...detail }
  hasContactResultChanges.value = false
  hasUnsavedChanges.value = false

  // 加载联系结果字典数据
  await loadContactResultOptions()

  // 查询HIS余额 - 使用正确的接口
  if (detail.patientId) {
    try {
      patientBalanceLoading.value = true
      patientBalanceError.value = ''
      patientBalance.value = 0

      const response = await api.get(`/api/refund/patient-balance/${detail.patientId}`)

      if (response.data && response.data.success) {
        patientBalance.value = response.data.data.balance || 0
      } else {
        patientBalanceError.value = response.data?.message || '查询余额失败'
      }
    } catch (error) {
      console.error('查询患者余额失败:', error)
      patientBalanceError.value = '查询余额失败: ' + (error.response?.data?.message || error.message)
    } finally {
      patientBalanceLoading.value = false
    }
  }

  // 检查初始状态，确保保存按钮状态正确
  checkForChanges()
}

const closeDetailDialog = () => {
  showDetailDialog.value = false
  selectedMasterId.value = null
  detailData.value = []
}

const closeContactDialog = async () => {
  // 检查是否有未保存的更改
  if (hasContactResultChanges.value) {
    const confirmClose = await showCustomConfirm(
      '确认退出',
      '您有未保存的联系记录更改，确定要退出吗？\n点击"确定"退出并丢弃更改，点击"取消"继续编辑。',
      '确定',
      '取消'
    )
    if (!confirmClose) {
      return // 用户选择继续编辑，不关闭弹窗
    }
  }

  showContactDialog.value = false
  selectedContactDetail.value = null
  patientBalance.value = 0
  patientBalanceError.value = ''
  hasContactResultChanges.value = false
  hasUnsavedChanges.value = false
  originalContactData.value = {}
}

// 确认关闭联系记录弹窗
const confirmCloseContactDialog = async () => {
  // 检查是否有未保存的更改
  if (hasContactResultChanges.value) {
    const confirmClose = await showCustomConfirm(
      '确认关闭',
      '您有未保存的联系记录更改，确定要关闭吗？\n\n点击"确定"关闭并丢弃更改\n点击"取消"继续编辑',
      '确定',
      '取消'
    )
    if (!confirmClose) {
      return // 用户选择继续编辑，不关闭弹窗
    }
  } else {
    // 没有未保存更改时，也给一个简单的确认提示
    const confirmClose = await showCustomConfirm(
      '确认关闭',
      '确定要关闭联系记录吗？',
      '确定',
      '取消'
    )
    if (!confirmClose) {
      return
    }
  }

  // 执行关闭操作
  await closeContactDialog()
}

// 导航到上一条联系记录
const prevContactRecord = async () => {
  // 检查是否有未保存的更改
  if (hasContactResultChanges.value) {
    const confirmSwitch = await showCustomConfirm(
      '确认切换',
      '您有未保存的联系记录更改，确定要切换到上一条记录吗？\n点击"确定"切换并丢弃更改，点击"取消"继续编辑。',
      '确定',
      '取消'
    )
    if (!confirmSwitch) {
      return
    }
  }

  if (currentContactIndex.value > 0) {
    const prevDetail = sortedDetailData.value[currentContactIndex.value - 1]
    await showContactRecord(prevDetail)
  }
}

// 导航到下一条联系记录
const nextContactRecord = async () => {
  // 检查是否有未保存的更改
  if (hasContactResultChanges.value) {
    const confirmSwitch = await showCustomConfirm(
      '确认切换',
      '您有未保存的联系记录更改，确定要切换到下一条记录吗？\n点击"确定"切换并丢弃更改，点击"取消"继续编辑。',
      '确定',
      '取消'
    )
    if (!confirmSwitch) {
      return
    }
  }

  if (currentContactIndex.value < sortedDetailData.value.length - 1) {
    const nextDetail = sortedDetailData.value[currentContactIndex.value + 1]
    await showContactRecord(nextDetail)
  }
}

// 联系记录相关函数
const getContactRecords = (detail) => {
  if (!detail) return []

  const records = []
  for (let i = 1; i <= 5; i++) {
    const notes = detail[`notes${i}`]
    const userNotes = detail[`userNotes${i}`]
    const contactTime = detail[`contactTime${i}`]

    records.push({
      index: i,
      notes: notes || '',
      userNotes: userNotes || '',
      contactTime: contactTime
    })
  }

  return records
}

const isContactRecordSaved = (index) => {
  if (!selectedContactDetail.value || !originalContactData.value) return false

  // 检查原始数据中是否有这个联系记录（即已保存到数据库的）
  const originalNotes = originalContactData.value[`notes${index}`]
  const originalContactTime = originalContactData.value[`contactTime${index}`]

  // 只有原始数据中有联系结果和联系时间，才认为是已保存的
  return originalNotes && originalNotes.trim() !== '' && originalContactTime
}

const canEditContactRecord = (index) => {
  if (!selectedContactDetail.value) return false

  // 第一次联系总是可以编辑
  if (index === 1) return true

  // 其他次数需要前一次已经保存
  return isContactRecordSaved(index - 1)
}

const onContactResultChange = (index) => {
  checkForChanges()
}

const onContactResultSelect = (index) => {
  checkForChanges()
  // 跟踪用户行为
  // try {
  //   const selectedResult = selectedContactDetail.value[`notes${index}`]
  //   if (selectedResult && userBehaviorService) {
  //     userBehaviorService.trackSelectResult(selectedResult)
  //   }
  // } catch (error) {
  //   console.warn('跟踪选择联系结果失败:', error)
  // }
}

const selectContactResult = (index, resultValue) => {
  if (!selectedContactDetail.value) return

  // 设置选中的联系结果
  selectedContactDetail.value[`notes${index}`] = resultValue

  // 检查变化
  checkForChanges()
}

const checkForChanges = () => {
  if (!selectedContactDetail.value) return

  // 检查联系结果的变化
  let hasChanges = false
  let hasUnsavedResults = false

  for (let i = 1; i <= 5; i++) {
    const currentNotes = selectedContactDetail.value[`notes${i}`] || ''
    const originalNotes = originalContactData.value[`notes${i}`] || ''

    // 检查是否有变化
    if (currentNotes !== originalNotes) {
      hasChanges = true
    }

    // 检查是否有未保存的联系结果（当前有联系结果但原始数据中没有保存到数据库）
    if (currentNotes && currentNotes.trim() !== '') {
      const originalContactTime = originalContactData.value[`contactTime${i}`]
      // 如果有联系结果但没有对应的联系时间，说明是未保存的
      if (!originalContactTime) {
        hasUnsavedResults = true
      }
    }
  }

  // 只要有变化或者有未保存的联系结果，就允许保存
  hasContactResultChanges.value = hasChanges || hasUnsavedResults
  hasUnsavedChanges.value = hasChanges || hasUnsavedResults
}

const saveContactRecord = async () => {
  if (!selectedContactDetail.value) return

  // 移除患者余额检查，允许余额为0时也能保存联系记录

  // 检查是否有联系结果的变化
  if (!hasContactResultChanges.value) {
    alert('请选择联系结果后再保存')
    return
  }

  try {
    loading.value = true
    loadingText.value = '保存联系记录中...'

    await retryOperation(async () => {
      // 获取当前时间，格式化为 ISO 字符串
      const currentTime = new Date().toISOString();

      // 计算实际的联系次数 - 根据填写的notes数量
      let actualContactCount = 0;
      const notesFields = ['notes1', 'notes2', 'notes3', 'notes4', 'notes5'];
      for (const field of notesFields) {
        if (selectedContactDetail.value[field] && selectedContactDetail.value[field].trim() !== '') {
          actualContactCount++;
        }
      }

      // 构建更新请求数据，包含完整的记录信息
      const updateData = {
        id: selectedContactDetail.value.id,
        masterId: selectedContactDetail.value.masterId,
        patientId: selectedContactDetail.value.patientId,
        accountId: selectedContactDetail.value.accountId,
        accountIndex: selectedContactDetail.value.accountIndex,
        balance: selectedContactDetail.value.balance,
        contactCount: actualContactCount, // 使用计算出的实际联系次数
        phoneNumber: selectedContactDetail.value.phoneNumber,
        patName: selectedContactDetail.value.patName,
        idNumber: selectedContactDetail.value.idNumber,
        sex: selectedContactDetail.value.sex,
        nextOfKin: selectedContactDetail.value.nextOfKin,
        // 联系记录字段 - 如果有联系结果则自动设置当前时间
        contactTime1: selectedContactDetail.value.contactTime1 || (selectedContactDetail.value.notes1 ? currentTime : null),
        notes1: selectedContactDetail.value.notes1,
        userNotes1: '',
        contactTime2: selectedContactDetail.value.contactTime2 || (selectedContactDetail.value.notes2 ? currentTime : null),
        notes2: selectedContactDetail.value.notes2,
        userNotes2: '',
        contactTime3: selectedContactDetail.value.contactTime3 || (selectedContactDetail.value.notes3 ? currentTime : null),
        notes3: selectedContactDetail.value.notes3,
        userNotes3: '',
        contactTime4: selectedContactDetail.value.contactTime4 || (selectedContactDetail.value.notes4 ? currentTime : null),
        notes4: selectedContactDetail.value.notes4,
        userNotes4: '',
        contactTime5: selectedContactDetail.value.contactTime5 || (selectedContactDetail.value.notes5 ? currentTime : null),
        notes5: selectedContactDetail.value.notes5,
        userNotes5: ''
      };

      // 调用正确的后台接口
      const response = await api.post('/api/RefundTaskDetail/update', updateData);

      if (response.data) {
        // 更新原始数据备份
        originalContactData.value = JSON.parse(JSON.stringify(selectedContactDetail.value))
        hasUnsavedChanges.value = false
        hasContactResultChanges.value = false

        // 更新详情数据中的对应记录
        const detailIndex = detailData.value.findIndex(item => item.id === selectedContactDetail.value.id);
        if (detailIndex !== -1) {
          Object.assign(detailData.value[detailIndex], updateData);
          // 同时更新当前显示的联系详情
          Object.assign(selectedContactDetail.value, updateData);
        }

        // 优化：直接更新前端联系统计数，避免重复调用接口
        // 检查是否是第一次保存联系记录（从0次变为有联系记录）
        const wasUncontacted = (originalContactData.value.contactCount || 0) === 0
        const nowContacted = actualContactCount > 0
        if (wasUncontacted && nowContacted) {
          updateContactStatsForTask(selectedContactDetail.value.masterId, 1)
        }

        // 显示跳转下一条记录的提示
        showNextRecordPromptWithDelay()

      } else {
        throw new Error('保存失败');
      }
    }, '保存联系记录')

  } catch (error) {
    console.error('保存联系记录失败:', error)
    alert(error.message || '保存联系记录失败，请重试')
  } finally {
    loading.value = false
  }
}

// 单个联系记录保存相关方法
const hasContactResultForRecord = (index) => {
  if (!selectedContactDetail.value) return false
  const notes = selectedContactDetail.value[`notes${index}`]
  return notes && notes.trim() !== ''
}

const canSaveContactRecord = (index) => {
  if (!selectedContactDetail.value) return false

  // 检查该记录是否已经保存
  if (isContactRecordSaved(index)) return false

  // 检查是否有联系结果
  const notes = selectedContactDetail.value[`notes${index}`]
  if (!notes || notes.trim() === '') return false

  // 检查是否可以编辑该记录
  return canEditContactRecord(index)
}

const hasUnsavedChangesForRecord = (index) => {
  if (!selectedContactDetail.value) return false

  const notes = selectedContactDetail.value[`notes${index}`]
  const originalNotes = originalContactData.value[`notes${index}`]

  // 如果有联系结果但与原始数据不同，说明有未保存的更改
  return notes && notes.trim() !== '' && notes !== originalNotes
}

const saveContactRecordForIndex = async (index) => {
  if (!selectedContactDetail.value || !canSaveContactRecord(index)) return

  try {
    loading.value = true
    loadingText.value = `保存第${index}次联系记录中...`

    await retryOperation(async () => {
      // 获取当前时间，格式化为 ISO 字符串
      const currentTime = new Date().toISOString();

      // 计算实际的联系次数 - 根据填写的notes数量
      let actualContactCount = 0;
      const notesFields = ['notes1', 'notes2', 'notes3', 'notes4', 'notes5'];
      for (const field of notesFields) {
        if (selectedContactDetail.value[field] && selectedContactDetail.value[field].trim() !== '') {
          actualContactCount++;
        }
      }

      // 构建更新请求数据，只更新指定的联系记录
      const updateData = {
        id: selectedContactDetail.value.id,
        masterId: selectedContactDetail.value.masterId,
        patientId: selectedContactDetail.value.patientId,
        accountId: selectedContactDetail.value.accountId,
        accountIndex: selectedContactDetail.value.accountIndex,
        balance: selectedContactDetail.value.balance,
        contactCount: actualContactCount,
        phoneNumber: selectedContactDetail.value.phoneNumber,
        patName: selectedContactDetail.value.patName,
        idNumber: selectedContactDetail.value.idNumber,
        sex: selectedContactDetail.value.sex,
        nextOfKin: selectedContactDetail.value.nextOfKin,
        // 保持所有现有的联系记录
        contactTime1: selectedContactDetail.value.contactTime1,
        notes1: selectedContactDetail.value.notes1,
        userNotes1: selectedContactDetail.value.userNotes1 || '',
        contactTime2: selectedContactDetail.value.contactTime2,
        notes2: selectedContactDetail.value.notes2,
        userNotes2: selectedContactDetail.value.userNotes2 || '',
        contactTime3: selectedContactDetail.value.contactTime3,
        notes3: selectedContactDetail.value.notes3,
        userNotes3: selectedContactDetail.value.userNotes3 || '',
        contactTime4: selectedContactDetail.value.contactTime4,
        notes4: selectedContactDetail.value.notes4,
        userNotes4: selectedContactDetail.value.userNotes4 || '',
        contactTime5: selectedContactDetail.value.contactTime5,
        notes5: selectedContactDetail.value.notes5,
        userNotes5: selectedContactDetail.value.userNotes5 || ''
      };

      // 为指定的联系记录设置时间（如果还没有时间的话）
      if (!selectedContactDetail.value[`contactTime${index}`]) {
        updateData[`contactTime${index}`] = currentTime;
        selectedContactDetail.value[`contactTime${index}`] = currentTime;
      }

      // 调用后台接口
      const response = await api.post('/api/RefundTaskDetail/update', updateData);

      // 记录操作日志
      try {
        const user = authStore.user
        const opLogData = {
          taskDetailId: selectedContactDetail.value?.id || 0,
          opName: '记录结果',
          username: user?.username || '',
          fullname: user?.fullName || ''
        }
        await api.post('/api/RefundTaskOpLog/create', opLogData)
        console.log('操作日志已记录:', opLogData)
      } catch (error) {
        console.error('记录操作日志失败:', error)
      }

      if (response.data) {
        // 更新原始数据备份中的对应字段
        originalContactData.value[`notes${index}`] = selectedContactDetail.value[`notes${index}`]
        originalContactData.value[`contactTime${index}`] = selectedContactDetail.value[`contactTime${index}`]

        // 重新检查变化状态
        checkForChanges()

        // 更新详情数据中的对应记录
        const detailIndex = detailData.value.findIndex(item => item.id === selectedContactDetail.value.id);
        if (detailIndex !== -1) {
          Object.assign(detailData.value[detailIndex], updateData);
        }

        // 优化：直接更新前端联系统计数，避免重复调用接口
        // 检查是否是第一次保存联系记录（从0次变为有联系记录）
        const wasUncontacted = (originalContactData.value.contactCount || 0) === 0
        const nowContacted = actualContactCount > 0
        if (wasUncontacted && nowContacted) {
          updateContactStatsForTask(selectedContactDetail.value.masterId, 1)
        }

        // 显示跳转下一条记录的提示
        showNextRecordPromptWithDelay()

      } else {
        throw new Error('保存失败');
      }
    }, `保存第${index}次联系记录`)

  } catch (error) {
    console.error(`保存第${index}次联系记录失败:`, error)
    alert(error.message || `保存第${index}次联系记录失败，请重试`)
  } finally {
    loading.value = false
  }
}

// 跳转下一条记录相关方法
const showNextRecordPromptWithDelay = () => {
  // 清除之前的定时器
  if (nextRecordPromptTimer.value) {
    clearTimeout(nextRecordPromptTimer.value)
  }

  // 延迟显示提示，避免界面闪烁
  nextRecordPromptTimer.value = setTimeout(() => {
    // 检查是否还有未联系的记录
    const nextUncontactedRecord = findNextUncontactedRecord()
    if (nextUncontactedRecord) {
      showNextRecordPrompt.value = true

      // 5秒后自动隐藏提示
      setTimeout(() => {
        if (showNextRecordPrompt.value) {
          dismissNextRecordPrompt()
        }
      }, 5000)
    }
  }, 1000)
}

const findNextUncontactedRecord = () => {
  // 在当前任务的详情数据中查找下一条未联系的记录
  const uncontactedRecords = detailData.value.filter(detail => (detail.contactCount || 0) === 0)

  if (uncontactedRecords.length > 0) {
    // 返回第一条未联系的记录
    return uncontactedRecords[0]
  }

  return null
}

const goToNextUncontactedRecord = async () => {
  const nextRecord = findNextUncontactedRecord()
  if (nextRecord) {
    // 隐藏提示
    dismissNextRecordPrompt()

    // 跳转到下一条记录
    await showContactRecord(nextRecord)
  }
}

const dismissNextRecordPrompt = () => {
  showNextRecordPrompt.value = false
  if (nextRecordPromptTimer.value) {
    clearTimeout(nextRecordPromptTimer.value)
    nextRecordPromptTimer.value = null
  }
}

// 加载联系结果字典数据
const loadContactResultOptions = async () => {
  try {
    const response = await api.post('/api/Dict/get-by-dict-id', {
      dictId: 7
    })

    if (response.data && Array.isArray(response.data)) {
      contactResultOptions.value = response.data
    } else {
      contactResultOptions.value = []
      console.warn('联系结果字典数据格式不正确:', response.data)
    }
  } catch (error) {
    console.error('获取联系结果选项失败:', error)
    contactResultOptions.value = []
  }
}

const refreshData = async () => {
  await loadMasterData()
  // 如果坐席统计信息已展开，则同时刷新坐席统计数据
  if (showAgentStats.value) {
    await loadAgentAccountStats()
  }
}

// 拨打电话并记录通话日志
const makePhoneCall = async (phoneNumber, contactName = '', callType = 'phone') => {
  try {
    // 首先检查患者充值记录
    if (selectedContactDetail.value?.patientId) {
      try {
        const rechargeResponse = await api.post(`/api/Refund/patient-recharge-count/${selectedContactDetail.value.patientId}`)
        
        if (rechargeResponse.data?.success && rechargeResponse.data?.data?.rechargeCount > 0) {
          await showCustomConfirm(
            '无法进行电话联系',
            `该患者近期在我院就诊（自2025年3月26日后有缴费记录），不属于门诊预交金退费患者类别，请不要拨打电话！`,
            '确定'
          )
          return
        }
      } catch (error) {
        console.error('查询患者充值记录失败:', error)
        // 如果查询失败，继续执行拨打电话流程
      }
    }
    
    // 获取当前用户信息
    console.log('authStore.user:', authStore.user)

    const user = authStore.user
    if (!user?.username) {
      alert('用户信息获取失败，请重新登录')
      return
    }
    // 调用坐席权限检查接口
    const statusResponse = await api.post('/api/AgentAccount/user-status', {
      username: user.username
    })
    console.log('accountStatus:', statusResponse.data?.data?.accountStatus)

    if (!statusResponse.data?.success) {
      //用户没有坐席账号权限，需要重新获取坐席账号后再拨打电话,自动退出当前界面回到上一个界面,让用户重新获取坐席账号
      alert('您尚未获取坐席账号权限,请稍等五分钟再进入系统尝试拨打电话!')
      // 关闭当前弹窗返回
      if (showContactDialog.value) {
        closeContactDialog()
        closeDetailDialog()
      }
      return
    } else if (statusResponse.data?.data?.accountStatus === 'active') {
      //坐席账号活跃,先调用queryAgentInfo查询坐席绑定电话是否与当前用户电话一致,一致就播出电话,不一致就提示用户坐席电话已变更,请重新获取坐席账号
      //console.log('statusResponse.data:', statusResponse.data)
      const queryResult = await queryAgentInfo(statusResponse.data.data.account)
      console.log('queryResult:', queryResult)
      console.log('user:', user)
      if (queryResult.mobile !== user.userPhone) {
        alert('坐席电话已变更,需要等待坐席电话自动注销后再尝试重新获取坐席账号,系统将自动返回上级菜单!')
        // 关闭当前弹窗返回
        if (showContactDialog.value) {
          closeContactDialog()
          closeDetailDialog()
        }
        return
      } else {
        //调用dialout拨打电话
        const callAcction = await dialout(statusResponse.data.data.account, phoneNumber)
        console.log('callAcction:', callAcction)

        // 记录操作日志
        try {
          const opLogData = {
            taskDetailId: selectedContactDetail.value?.id || 0,
            opName: '打电话',
            username: user?.username || '',
            fullname: user?.fullName || '',
            actionId: callAcction.actionID
          }
          await api.post('/api/RefundTaskOpLog/create', opLogData)
          console.log('操作日志已记录:', opLogData)
        } catch (error) {
          console.error('记录操作日志失败:', error)
        }
      }
    } else if (statusResponse.data?.data?.accountStatus !== 'active') {
      //坐席账号不活跃,先对行级锁锁定坐席账号信息再清理该坐席账号
      alert('您尚未获取坐席账号权限,请稍等五分钟再进入系统尝试拨打电话!')

      // 关闭当前弹窗返回
      if (showContactDialog.value) {
        closeContactDialog()
        closeDetailDialog()
      }
      return
    } else {
      alert('其他问题无法拨打电话,请稍等五分钟再进入系统尝试拨打电话!')
      // 关闭当前弹窗返回
      if (showContactDialog.value) {
        closeContactDialog()
        closeDetailDialog()
      }
      return
    }
  } catch (error) {
    console.error('拨打电话失败:', error)
  }
}

// 处理坐席账号申请和鉴权流程
const handleAgentAccountProcess = async (user, masterId) => {

  try {
    // 1. 检查并获取用户手机号
    let userPhone = user.userPhone
    if (!userPhone) {
      // 从本地存储获取
      const storedUser = JSON.parse(localStorage.getItem('user') || '{}')
      userPhone = storedUser.userPhone
      
      // 如果从本地存储获取到手机号，同步到authStore
      if (userPhone && authStore.user) {
        authStore.user.userPhone = userPhone
      }

      if (!userPhone) {
        // 提示用户输入手机号
        const inputResult = await showCustomInput(
          '输入手机号',
          '请输入您的当前手机号，用于接收坐席账号信息：',
          '请输入11位手机号',
          '确定',
          '取消',
          (value) => {
            if (!value) {
              return false
            }
            if (!validatePhoneNumber(value)) {
              return false
            }
            return true
          }
        )

        if (!inputResult.confirmed) {
          await cancelAgentAccount(agentAccount.id, user.username)
          return
        }

        userPhone = inputResult.value
        if (!userPhone || !validatePhoneNumber(userPhone)) {
          await showCustomConfirm('错误', '手机号格式不正确，请重新尝试')
          await cancelAgentAccount(agentAccount.id, user.username)
          return
        }

        // 更新本地存储
        const updatedUser = { ...storedUser, userPhone }
        localStorage.setItem('user', JSON.stringify(updatedUser))

        // 同步更新authStore中的user对象
        authStore.user.userPhone = userPhone

        // 调用接口更新用户手机号
        try {
          await api.post('/api/uumuser/update-phone', {
            userName: user.username,
            userPhone: userPhone
          })
        } catch (error) {
          console.error('更新用户手机号失败:', error)
          // 继续流程，不中断
        }
      }
    }
    
    // 2. 申请坐席账号使用权
    const applyResponse = await api.post('/api/AgentAccount/apply', {
      username: user.username,
      fullName: user.fullName,
      userPhone: user.userPhone
    })

    if (!applyResponse.data?.success) {
      alert('申请坐席账号失败：' + (applyResponse.data?.message || '未知错误'))
      return
    }

    const agentAccount = applyResponse.data.data
    console.log('申请坐席账号成功:', agentAccount)

    // 3. 调用7moor鉴权接口
    const authResult = await authenticate7moor(agentAccount)
    if (!authResult.success) {
      alert('鉴权失败：' + authResult.message)
      await cancelAgentAccount(agentAccount.id, user.username)
      return
    }
    // // 4. 修改坐席手机号为空值再修改为当前手机号
    // const updatePhoneNullResult = await updateAgentMobile(agentAccount, '')
    // if (!updatePhoneNullResult.success) {
    //   alert('修改坐席手机号失败：' + updateResult.message)
    //   await cancelAgentAccount(agentAccount.id, user.username)
    //   return
    // }

    // 4. 修改坐席手机号
    const updateResult = await updateAgentMobile(agentAccount, userPhone)
    if (!updateResult.success) {
      alert('修改坐席手机号失败：' + updateResult.message)
      await cancelAgentAccount(agentAccount.id, user.username)
      return
    }

    // 5. 确认坐席账号所有权
    const confirmResponse = await api.post('/api/AgentAccount/confirm', {
      accountId: agentAccount.id,
      username: user.username,
      isConfirm: true,
      userPhone: userPhone
    })

    if (!confirmResponse.data?.success) {
      alert('确认坐席账号失败：' + (confirmResponse.data?.message || '未知错误'))
      return
    }

    //alert('坐席权限获取成功！现在可以查看任务详情了。')
    // 重新调用showDetails显示任务详情
    showDetailDialog.value = true

    detailLoading.value = true

    await retryOperation(async () => {
      const response = await api.post('/api/RefundTaskDetail/get-by-master-id', { id: masterId })

      if (response.data) {
        detailData.value = response.data || []
        // 对身份证和电话号码进行脱敏处理
        detailData.value.forEach(item => {
          if (item.idNumber) {
            item.maskedIdNumber = maskIdNumber(item.idNumber)
          }
          if (item.phoneNumber) {
            item.maskedPhoneNumber = maskPhoneNumber(item.phoneNumber)
          }
        })
      } else {
        throw new Error('未获取到数据')
      }
    }, '加载详情')

  } catch (error) {
    console.error('坐席账号申请流程失败:', error)
    alert('坐席账号申请流程失败：' + (error.response?.data?.message || error.message))
  } finally {
    detailLoading.value = false
  }
}

// 取消确认坐席账号
const cancelAgentAccount = async (accountId, username) => {
  try {
    await api.post('/api/AgentAccount/confirm', {
      accountId: accountId,
      username: username,
      isConfirm: false
    })
  } catch (error) {
    console.error('取消确认坐席账号失败:', error)
  }
}

// 手机号验证函数
const validatePhoneNumber = (phone) => {
  const phoneRegex = /^1[3-9]\d{9}$/
  return phoneRegex.test(phone)
}

// 生成签名
const generateSignature = (accountId, apiSecret, timestamp) => {
  const signString = accountId + apiSecret + timestamp
  //console.log('signString:', signString)
  //console.log('MD5:', CryptoJS.MD5(signString).toString().toUpperCase())
  return CryptoJS.MD5(signString).toString().toUpperCase()
}

// 记录账户操作日志
const recordAccountOpLog = async (funcname, apiurl, accountid, requestbody, responsedata, userPhone, username, fullName) => {
  try {
    await api.post('/api/AccountOpLog/Create', {
      funcname: funcname,
      apiurl: apiurl,
      accountid: accountid,
      requestbody: requestbody ? JSON.stringify(requestbody) : null,
      responsedata: responsedata ? JSON.stringify(responsedata) : null,
      mobile: userPhone,
      username: username,
      fullname: fullName
    })
  } catch (error) {
    console.error('记录账户操作日志失败:', error)
    // 不影响主业务流程，只记录错误
  }
}

// 7moor鉴权
const authenticate7moor = async (agentAccount) => {
  try {
    const timestamp = generateAccountAuthTimestamp()
    const sig = generateSignature(agentAccount.accountId, agentAccount.apiSecret, timestamp)
    const authorization = btoa(`${agentAccount.accountId}:${timestamp}`)

    const response = await fetch(`${agentAccount.apiUrl}v20160818/customer/getTemplate/${agentAccount.accountId}?sig=${sig}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json;charset=utf-8',
        'Authorization': `${authorization}`
      },
      body: JSON.stringify({})
    })

    const data = await response.json()

    // 记录账户操作日志
    const user = authStore.user
    recordAccountOpLog(
      '7moor鉴权',
      `${agentAccount.apiUrl}v20160818/customer/getTemplate/${agentAccount.accountId}`,
      agentAccount.accountId,
      {},
      data,
      user?.userPhone || null,
      user?.username || null,
      user?.fullName || null
    )

    return {
      success: data.code === 200,
      data: data,
      code: data.code,
      message: data.msg || '鉴权请求完成',
      status: response.status,
      timestamp: timestamp,
      sig: sig,
      authorization: authorization
    }
  } catch (error) {
    console.error('7moor鉴权失败:', error)
    return {
      success: false,
      message: error.message || '鉴权请求失败'
    }
  }
}

// 修改坐席手机号
const updateAgentMobile = async (agentAccount, mobile) => {
  try {
    const timestamp = generateAccountAuthTimestamp()
    const sig = generateSignature(agentAccount.accountId, agentAccount.apiSecret, timestamp)
    const authorization = btoa(`${agentAccount.accountId}:${timestamp}`)

    const requestBody = {
      exten: agentAccount.exten,
      mobile: mobile
    }

    const response = await fetch(`${agentAccount.apiUrl}v20160818/user/updateUser/${agentAccount.accountId}?sig=${sig}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json;charset=utf-8',
        'Authorization': `${authorization}`
      },
      body: JSON.stringify(requestBody)
    })

    const data = await response.json()
    //console.log('修改坐席手机号返回值:', data)

    // 记录账户操作日志
    const user = authStore.user
    recordAccountOpLog(
      '修改坐席手机号',
      `${agentAccount.apiUrl}v20160818/user/updateUser/${agentAccount.accountId}`,
      agentAccount.accountId,
      requestBody,
      data,
      mobile || null,
      user?.username || null,
      user?.fullName || null
    )

    return {
      success: data.code === 200,
      data: data,
      code: data.code,
      message: data.message || '修改手机号请求完成',
      status: response.status,
      requestBody: requestBody,
      timestamp: timestamp,
      sig: sig,
      authorization: `${authorization}`
    }
  } catch (error) {
    console.error('修改坐席手机号失败:', error)
    return {
      success: false,
      message: error.message || '修改手机号请求失败'
    }
  }
}

// 查询坐席信息
const queryAgentInfo = async (agentAccount) => {
  try {
    const timestamp = generateAccountAuthTimestamp()
    const sig = generateSignature(agentAccount.accountId, agentAccount.apiSecret, timestamp)
    const authorization = btoa(`${agentAccount.accountId}:${timestamp}`)

    const url = `${agentAccount.apiUrl}v20160818/account/getCCAgentsByAcc/${agentAccount.accountId}?sig=${sig}`

    const requestBody = {
      Exten: agentAccount.exten
    }

    const headers = {
      'Content-Type': 'application/json;charset=utf-8',
      'Authorization': authorization
    }

    const response = await fetch(url, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(requestBody)
    })

    const result = await response.json()
    console.log('查询坐席信息返回值:', result)

    // 根据API文档处理返回值
    const isSuccess = result.code === 200

    // 提取mobile字段作为返回值
    //console.log('result.data:', result.data)
    console.log('result.data[0]:', result.data[0].mobile)


    let mobile = null
    if (isSuccess && result.data && result.data.length > 0) {
      mobile = result.data[0].mobile
    }

    // 记录账户操作日志
    const user = authStore.user
    recordAccountOpLog(
      '查询坐席信息',
      url,
      agentAccount.accountId,
      requestBody,
      result,
      mobile,
      user?.username || null,
      user?.fullName || null
    )

    return {
      success: isSuccess,
      data: result,
      code: result.code,
      message: result.message,
      agentData: result.data || null,
      mobile: mobile, // 返回mobile字段
      status: response.status,
      requestBody,
      timestamp,
      sig,
      authorization
    }
  } catch (error) {
    console.error('查询坐席信息错误:', error)
    return {
      success: false,
      error: error.message,
      mobile: null,
      timestamp: generateAccountAuthTimestamp()
    }
  }
}

// 生成唯一ActionID
const generateActionID = () => {
  return 'ACTION_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
}

// 外呼函数
const dialout = async (agentAccount, targetPhone) => {
  try {
    const timestamp = generateAccountAuthTimestamp()
    const sig = generateSignature(agentAccount.accountId, agentAccount.apiSecret, timestamp)
    const authorization = btoa(`${agentAccount.accountId}:${timestamp}`)

    const url = `${agentAccount.apiUrl}v20180426/call/dialout/${agentAccount.accountId}?sig=${sig}`

    const requestBody = {
      FromExten: agentAccount.fromExten,
      Exten: targetPhone,
      ExtenType: 'Local',
      ActionID: generateActionID(),
      DialoutStrVar: '',
      OutShow: ''
    }

    const headers = {
      'Content-Type': 'application/json;charset=utf-8',
      'Authorization': authorization
    }

    console.log('外呼参数:', {
      url,
      headers,
      body: requestBody
    })

    const response = await fetch(url, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(requestBody)
    })

    const result = await response.json()

    // 根据API文档处理外呼返回值
    const isSuccess = result.Succeed === true || result.Succeed === 'true'

    // 记录账户操作日志
    const user = authStore.user
    recordAccountOpLog(
      '外呼',
      url,
      agentAccount.accountId,
      requestBody,
      result,
      targetPhone,
      user?.username || null,
      user?.fullName || null
    )

    // 如果外呼成功，调用坐席账号操作记录接口更新状态
    if (isSuccess) {
      try {
        if (user?.username && agentAccount.id) {
          await api.post('/api/AgentAccount/record-action', {
            accountId: agentAccount.id,
            username: user.username
          })
          console.log('坐席账号状态已更新')
        }
      } catch (recordError) {
        console.error('更新坐席账号状态失败:', recordError)
        // 不影响外呼结果，继续返回
      }
    }

    return {
      success: isSuccess,
      data: result,
      response: result.Response,
      actionID: result.ActionID,
      succeed: result.Succeed,
      message: result.Message,
      status: response.status,
      requestBody,
      timestamp
    }
  } catch (error) {
    console.error('外呼错误:', error)
    return {
      success: false,
      error: error.message,
      timestamp: generateAccountAuthTimestamp()
    }
  }
}

const goBack = () => {
  router.push('/')
}

const logout = () => {
  authStore.logout()
  router.push('/login')
}

// 自定义确认对话框方法
const showCustomConfirm = (title, message, confirmText = '确定', cancelText = '取消') => {
  return new Promise((resolve) => {
    confirmDialogData.value = {
      title,
      message,
      confirmText,
      cancelText,
      onConfirm: () => {
        showConfirmDialog.value = false
        resolve(true)
      },
      onCancel: () => {
        showConfirmDialog.value = false
        resolve(false)
      }
    }
    showConfirmDialog.value = true
  })
}

const handleConfirmDialogConfirm = () => {
  if (confirmDialogData.value.onConfirm) {
    confirmDialogData.value.onConfirm()
  }
}

const handleConfirmDialogCancel = () => {
  if (confirmDialogData.value.onCancel) {
    confirmDialogData.value.onCancel()
  }
}

// 自定义输入对话框函数
const showCustomInput = (title, message, placeholder = '', confirmText = '确定', cancelText = '取消', validator = null) => {
  return new Promise((resolve) => {
    inputDialogData.value = {
      title,
      message,
      placeholder,
      inputValue: '',
      confirmText,
      cancelText,
      validator,
      onConfirm: () => {
        const value = inputDialogData.value.inputValue.trim()
        if (validator && !validator(value)) {
          return // 验证失败，不关闭对话框
        }
        showInputDialog.value = false
        resolve({ confirmed: true, value })
      },
      onCancel: () => {
        showInputDialog.value = false
        resolve({ confirmed: false, value: null })
      }
    }
    showInputDialog.value = true

    // 延迟聚焦到输入框，确保DOM已渲染
    nextTick(() => {
      const inputField = document.querySelector('.input-control')
      if (inputField) {
        inputField.focus()
      }
    })
  })
}

const handleInputDialogConfirm = () => {
  if (inputDialogData.value.onConfirm) {
    inputDialogData.value.onConfirm()
  }
}

const handleInputDialogCancel = () => {
  if (inputDialogData.value.onCancel) {
    inputDialogData.value.onCancel()
  }
}

// 倒计时相关方法
const updateCountdown = () => {
  const now = new Date()
  const startDate = new Date(taskConfig.countdown.startDate)
  const deadlineDate = new Date(startDate.getTime() + taskConfig.countdown.daysLimit * 24 * 60 * 60 * 1000)
  const timeDiff = deadlineDate.getTime() - now.getTime()

  if (timeDiff <= 0) {
    // 倒计时结束
    countdownData.value = {
      days: 0,
      hours: 0,
      minutes: 0,
      seconds: 0
    }
    if (countdownTimer.value) {
      clearInterval(countdownTimer.value)
      countdownTimer.value = null
    }
    return
  }

  const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
  const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
  const minutes = Math.floor((timeDiff % (1000 * 60 * 60)) / (1000 * 60))
  const seconds = Math.floor((timeDiff % (1000 * 60)) / 1000)

  countdownData.value = {
    days: days.toString().padStart(2, '0'),
    hours: hours.toString().padStart(2, '0'),
    minutes: minutes.toString().padStart(2, '0'),
    seconds: seconds.toString().padStart(2, '0')
  }
}

// 余额变动查询方法
// 退费申请查询相关响应式变量
const refundQueryData = ref([])
const refundQueryLoading = ref(false)
const refundQueryDialog = ref(false)
const refundQueryError = ref('')

const handleRefundMasterQuery = async () => {
  if (!selectedContactDetail.value?.patientId) {
    await showCustomAlert('提示', '请先选择患者')
    return
  }

  refundQueryLoading.value = true
  refundQueryError.value = ''
  refundQueryData.value = []

  try {
    const response = await api.post('/api/PatientRefundQuery/get-refund-info', {
      patientId: selectedContactDetail.value.patientId
    })

    if (response.data?.success) {
      refundQueryData.value = response.data.data || []
      refundQueryDialog.value = true
    } else {
      refundQueryError.value = response.data?.message || '查询失败'
      await showCustomAlert('查询失败', refundQueryError.value)
    }
  } catch (error) {
    console.error('查询退费申请失败:', error)
    refundQueryError.value = '查询失败: ' + (error.response?.data?.message || error.message)
    await showCustomAlert('查询失败', refundQueryError.value)
  } finally {
    refundQueryLoading.value = false
  }
}

const closeRefundQueryDialog = () => {
  refundQueryDialog.value = false
  refundQueryData.value = []
  refundQueryError.value = ''
}



const startCountdown = () => {
  if (taskConfig.ui.showCountdown) {
    updateCountdown()
    countdownTimer.value = setInterval(updateCountdown, 1000)
  }
}

const stopCountdown = () => {
  if (countdownTimer.value) {
    clearInterval(countdownTimer.value)
    countdownTimer.value = null
  }
}

// 生命周期
onMounted(() => {
  loadMasterData()

  // 启动倒计时
  startCountdown()

  // 监听网络状态变化
  window.addEventListener('online', () => {
    isOffline.value = false
    checkNetworkStatus()
  })

  window.addEventListener('offline', () => {
    isOffline.value = true
  })

  // 初始检查网络状态
  checkNetworkStatus()
})

// 组件卸载时清理定时器
onBeforeUnmount(() => {
  stopCountdown()
})
</script>

<style scoped>
/* 移动端专用样式 */
.mobile-refund-task {
  min-height: 100vh;
  background: #f8f9fa;
  padding-bottom: env(safe-area-inset-bottom);
}

/* 顶部导航栏 */
.mobile-header {
  background: linear-gradient(135deg, #e3f2fd, #bbdefb);
  color: #1565c0;
  padding: 0.32rem;
  padding-top: calc(0.32rem + env(safe-area-inset-top));
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08);
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid #90caf9;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
  color: #0d47a1;
  line-height: 1.2;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: 32px;
}

.header-title i {
  font-size: 1.1rem;
  line-height: 1;
}

.header-actions {
  display: flex;
  gap: 0.5rem;
}

.header-actions .btn {
  border-radius: 6px;
  width: 32px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-color: #1976d2;
  color: #1976d2;
  background: rgba(255, 255, 255, 0.8);
  font-size: 0.85rem;
}

.header-actions .btn:hover {
  background: #1976d2;
  color: white;
  border-color: #1976d2;
}

/* 主要内容区域 */
.mobile-content {
  padding: 1rem;
}

/* 创建任务区域 */
.create-task-section {
  margin-bottom: 1.5rem;
}

.create-task-btn {
  border-radius: 12px;
  padding: 1rem;
  font-size: 1.1rem;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
}

/* 任务限制信息样式 */
.task-limit-info,
.single-limit-info,
.create-tip {
  margin-top: 1rem;
}

.task-limit-info .alert {
  margin-bottom: 0;
  padding: 0.75rem;
  border-radius: 8px;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: #e3f2fd;
  border-color: #2196f3;
  color: #1976d2;
}

.single-limit-info .alert {
  margin-bottom: 0;
  padding: 0.6rem;
  border-radius: 6px;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: #f5f5f5;
  border-color: #9e9e9e;
  color: #616161;
}

.create-tip .alert {
  margin-bottom: 0;
  padding: 0.75rem;
  border-radius: 8px;
  font-size: 0.9rem;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

.create-tip .alert i {
  margin-top: 0.1rem;
  flex-shrink: 0;
}

/* 倒计时样式 */
.countdown-section {
  margin-top: 1rem;
}

.countdown-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  padding: 1.25rem;
  color: white;
  box-shadow: 0 8px 32px rgba(102, 126, 234, 0.3);
  position: relative;
  overflow: hidden;
}

.countdown-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.1) 100%);
  pointer-events: none;
}

.countdown-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
  position: relative;
  z-index: 1;
}

.countdown-header i {
  font-size: 1.2rem;
  color: rgba(255, 255, 255, 0.9);
}

.countdown-title {
  font-size: 1rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.95);
}

.countdown-content {
  position: relative;
  z-index: 1;
}

.countdown-display {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.countdown-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  padding: 0.75rem 0.5rem;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  min-width: 60px;
}

.countdown-number {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  color: white;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.countdown-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.8);
  margin-top: 0.25rem;
}

.countdown-separator {
  font-size: 1.5rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.7);
  margin: 0 0.25rem;
}

.countdown-info {
  text-align: center;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.countdown-text {
  display: block;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 0.25rem;
}

.countdown-deadline {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.95);
}

/* 倒计时响应式调整 */
@media (max-width: 576px) {
  .countdown-card {
    padding: 1rem;
  }

  .countdown-item {
    padding: 0.5rem 0.375rem;
    min-width: 50px;
  }

  .countdown-number {
    font-size: 1.25rem;
  }

  .countdown-label {
    font-size: 0.7rem;
  }

  .countdown-separator {
    font-size: 1.25rem;
    margin: 0 0.125rem;
  }
}

/* 任务卡片 */
.task-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.task-card {
  background: white;
  border-radius: 8px;
  padding: 0.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
}

.task-card:active {
  transform: scale(0.98);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.task-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.task-id {
  font-weight: 600;
  color: #007bff;
  font-size: 1.1rem;
}

.task-date {
  font-size: 0.85rem;
  color: #6c757d;
}

/* 进度条 */
.task-progress {
  margin-bottom: 0.5rem;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.progress-text {
  font-size: 0.9rem;
  color: #495057;
}

.progress-numbers {
  font-weight: 600;
  color: #007bff;
}

.progress-bar-container {
  height: 8px;
  background: #e9ecef;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 0.25rem;
}

.progress-bar-fill {
  height: 100%;
  transition: width 0.3s ease;
  border-radius: 4px;
}

.progress-bar-fill.none {
  background: #dc3545;
}

.progress-bar-fill.started {
  background: #ffc107;
}

.progress-bar-fill.good {
  background: #17a2b8;
}

.progress-bar-fill.complete {
  background: #28a745;
}

.progress-percentage {
  text-align: right;
  font-size: 0.8rem;
  color: #6c757d;
}

/* 统计信息 */
.task-stats {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.stat-item {
  flex: 1;
  text-align: center;
  padding: 0.3rem;
  background: #f8f9fa;
  border-radius: 6px;
}

.stat-label {
  font-size: 0.8rem;
  color: #6c757d;
  margin-bottom: 0.25rem;
}

.stat-value {
  font-weight: 600;
  font-size: 1rem;
}

.stat-value.amount {
  color: #28a745;
}

/* 备注 */
.task-notes {
  font-size: 0.9rem;
  color: #6c757d;
  background: #f8f9fa;
  padding: 0.4rem;
  border-radius: 6px;
  margin-bottom: 0.3rem;
}

/* 操作指示 */
.task-action {
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  color: #6c757d;
  font-size: 1.2rem;
}

/* 空状态 */
.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: #6c757d;
}

.empty-icon {
  font-size: 4rem;
  margin-bottom: 1rem;
  opacity: 0.5;
}

.empty-title {
  font-size: 1.2rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.empty-subtitle {
  font-size: 0.9rem;
}

/* 加载状态 */
.loading-state {
  text-align: center;
  padding: 3rem 1rem;
}

.loading-spinner {
  margin-bottom: 1rem;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #e9ecef;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.loading-text {
  color: #6c757d;
  font-size: 0.9rem;
}

/* 移动端弹窗 */
.mobile-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 1000;
  display: flex;
  align-items: flex-end;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}

.mobile-modal.show {
  opacity: 1;
  visibility: visible;
}

.modal-content {
  background: white;
  width: 100%;
  max-height: 90vh;
  border-radius: 16px 16px 0 0;
  transform: translateY(100%);
  transition: transform 0.3s ease;
  display: flex;
  flex-direction: column;
}

.mobile-modal.show .modal-content {
  transform: translateY(0);
}

.modal-header {
  padding: 1rem;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  gap: 1rem;
}

.header-left {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
}

.title-navigation-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  /* 统一高度 */
  position: relative;
}

.header-right {
  flex-shrink: 0;
  margin-left: 1rem;
}

.modal-title {
  font-size: 1.32rem;
  /* 增大20% */
  font-weight: 600;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  height: 40px;
  /* 与导航组统一高度 */
  display: flex;
  align-items: center;
  flex-shrink: 1;
  max-width: calc(100% - 120px);
  /* 为导航按钮组留出空间 */
}

.header-navigation {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 6px;
  padding: 0.25rem 0.5rem;
  height: 40px;
  /* 与标题统一高度 */
  flex-shrink: 0;
  position: absolute;
  right: 0;
  top: 0;
}

.nav-btn-header {
  background: white;
  border: 1px solid #dee2e6;
  color: #6c757d;
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  min-width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.nav-btn-header:hover:not(:disabled) {
  background: #e9ecef;
  border-color: #adb5bd;
  color: #495057;
}

.nav-btn-header:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.nav-info-header {
  font-size: 0.75rem;
  color: #6c757d;
  padding: 0 0.5rem;
  font-weight: 500;
  white-space: nowrap;
}

.modal-close {
  background: none;
  border: none;
  font-size: 1.2rem;
  color: #6c757d;
  padding: 0.5rem;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.modal-close:hover {
  background: #f8f9fa;
  color: #495057;
}

.modal-body {
  padding: 1rem;
  overflow-y: auto;
  flex: 1;
}

/* 详情统计 */
.detail-stats {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.stat-card {
  flex: 1;
  text-align: center;
  padding: 1rem;
  background: #f8f9fa;
  border-radius: 8px;
}

.stat-number {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.25rem;
}

.stat-label {
  font-size: 0.8rem;
  color: #6c757d;
}

/* 患者卡片 */
.patient-list {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 0.25rem 0;
}

.patient-card {
  background: #ffffff;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 0.75rem;
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.patient-card:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  border-color: #007bff;
}

.patient-card.uncontacted {
  border-left: 4px solid #ffc107;
  background: #fffbf0;
}

.patient-card:active {
  transform: scale(0.98);
}

.patient-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}

.patient-name {
  font-weight: 600;
  font-size: 1.2rem;
  color: #2c3e50;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.patient-name i {
  color: #007bff;
  font-size: 1.1rem;
}

.patient-contact-count span {
  background: #007bff;
  color: white;
  padding: 0.2rem 0.5rem;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  min-width: 40px;
  text-align: center;
  display: inline-block;
}

.patient-details {
  margin-bottom: 0.5rem;
}

.detail-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.25rem;
  padding: 0.125rem 0;
}

.detail-label {
  color: #6c757d;
  font-size: 0.9rem;
  font-weight: 500;
  min-width: 60px;
}

.detail-value {
  color: #2c3e50;
  font-size: 1rem;
  font-weight: 600;
  text-align: right;
  flex: 1;
}

.detail-value.phone {
  color: #007bff;
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.detail-value.phone i {
  font-size: 0.875rem;
}

.detail-value.amount {
  color: #28a745;
  font-weight: 700;
  font-size: 1.125rem;
}

.contact-status {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid #e9ecef;
}

.status-contacted {
  color: #28a745;
  font-size: 0.875rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.status-contacted i {
  font-size: 1rem;
}

.status-uncontacted {
  color: #6c757d;
  font-size: 0.875rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.status-uncontacted i {
  font-size: 1rem;
}

.patient-action {
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  color: #6c757d;
}

/* 联系记录相关样式 */
.contact-records-section {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  overflow: hidden;
}

.section-header {
  padding: 1rem;
  background: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.section-header h6 {
  margin: 0;
  font-weight: 600;
  color: #495057;
}

/* 导航按钮和保存按钮布局样式 */
.action-buttons {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.navigation-group {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  padding: 0.15rem 0.3rem;
  margin-right: auto;
}

.nav-btn {
  min-width: 28px;
  height: 28px;
  padding: 0.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  font-size: 0.8rem;
  border: 1px solid #dee2e6;
  background: white;
  transition: all 0.2s ease;
}

.nav-btn:hover:not(:disabled) {
  background: #e9ecef;
  border-color: #adb5bd;
}

.nav-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.nav-info {
  font-size: 0.75rem;
  font-weight: 600;
  color: #495057;
  padding: 0 0.15rem;
  white-space: nowrap;
  min-width: 35px;
  text-align: center;
}

.save-btn.btn.btn-success {
  font-size: 1.1rem !important;
  padding: 1rem 2rem !important;
  font-weight: 600 !important;
  border-radius: 8px !important;
  min-height: 48px !important;
  min-width: 140px !important;
  width: auto !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 0.5rem !important;
  transition: all 0.2s ease !important;
  box-shadow: 0 2px 8px rgba(40, 167, 69, 0.2) !important;
  white-space: nowrap !important;
}

.save-btn.btn.btn-success:hover:not(:disabled) {
  transform: translateY(-1px) !important;
  box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3) !important;
}

.save-section .btn {
  font-size: 0.9rem;
  padding: 0.5rem 1rem;
}

.save-status {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid #e9ecef;
}

.status-message {
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.status-message.success {
  color: #28a745;
}

.status-message.warning {
  color: #ffc107;
}

.contact-records-list {
  padding: 1rem;
}

.contact-record-item {
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1rem;
  background: #fafafa;
}

.contact-record-item:last-child {
  margin-bottom: 0;
}

.contact-record-item.saved {
  background: #f8fff8;
  border-color: #28a745;
}

.contact-record-item.disabled {
  background: #f8f9fa;
  opacity: 0.7;
}

.record-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #e9ecef;
}

.record-number {
  font-weight: 600;
  color: #495057;
  font-size: 1rem;
}

.record-time {
  font-size: 0.8rem;
  color: #6c757d;
}

.form-group {
  margin-bottom: 0;
}

.form-label {
  font-size: 0.9rem;
  font-weight: 600;
  color: #495057;
  margin-bottom: 0.75rem;
  display: block;
}

/* 已保存结果样式 */
.form-value.saved {
  background: #e8f5e8;
  border: 1px solid #28a745;
  border-radius: 8px;
  padding: 1rem;
}

.saved-result {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.saved-result i {
  color: #28a745;
  font-size: 1.2rem;
}

.result-text {
  flex: 1;
  font-size: 1rem;
  font-weight: 600;
  color: #155724;
}

.saved-badge {
  background: #28a745;
  color: white;
  font-size: 0.75rem;
  padding: 0.25rem 0.5rem;
  border-radius: 12px;
  font-weight: 600;
}

/* 联系结果选择器样式 */
.contact-result-selector {
  background: white;
  border: 1px solid #dee2e6;
  border-radius: 8px;
  overflow: hidden;
}

/* 下拉菜单和保存按钮容器 */
.result-select-container {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
}

/* 下拉菜单样式 */
.contact-result-select {
  flex: 1;
  min-width: 0;
  border: 1px solid #ced4da;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font-size: 0.95rem;
  background-color: white;
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.contact-result-select:focus {
  border-color: #80bdff;
  outline: 0;
  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

/* 内联保存按钮样式 */
.save-btn-inline {
  flex-shrink: 0;
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  border-radius: 6px;
  border: none;
  background-color: #28a745;
  color: white;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-weight: 500;
}

.save-btn-inline:hover:not(:disabled) {
  background-color: #218838;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.save-btn-inline:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.save-btn-inline:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  opacity: 0.6;
}

.save-btn-inline i {
  font-size: 0.875rem;
}

.result-options {
  display: flex;
  flex-direction: column;
}

.result-option {
  padding: 1rem;
  border-bottom: 1px solid #f1f3f4;
  cursor: pointer;
  transition: all 0.2s ease;
  background: white;
}

.result-option:last-child {
  border-bottom: none;
}

.result-option:hover {
  background: #f8f9fa;
}

.result-option.selected {
  background: #e3f2fd;
  border-color: #2196f3;
}

.result-option:active {
  transform: scale(0.98);
}

.option-content {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.option-content i {
  font-size: 1.2rem;
  color: #6c757d;
  transition: color 0.2s ease;
}

.result-option.selected .option-content i {
  color: #2196f3;
}

.option-text {
  font-size: 1rem;
  font-weight: 500;
  color: #495057;
  line-height: 1.4;
}

.result-option.selected .option-text {
  color: #1976d2;
  font-weight: 600;
}

/* 禁用状态样式 */
.form-value.disabled {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  padding: 1rem;
  color: #6c757d;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.form-value.disabled i {
  color: #ffc107;
  font-size: 1.1rem;
}

.form-value.disabled span {
  font-size: 0.95rem;
}

.no-records {
  text-align: center;
  padding: 2rem;
  color: #6c757d;
  font-size: 0.9rem;
}

.no-records i {
  font-size: 2rem;
  margin-bottom: 0.5rem;
  opacity: 0.5;
  display: block;
}

/* 联系信息卡片 */
.contact-info-card {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1rem;
}

/* 患者电话美化样式 */
.patient-phone-section {
  margin-bottom: 1.5rem;
}

.patient-phone-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.patient-phone-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
  pointer-events: none;
}

.patient-phone-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

.phone-icon {
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  backdrop-filter: blur(10px);
}

.phone-icon i {
  font-size: 1.5rem;
  color: white;
}

.phone-info {
  flex: 1;
  min-width: 0;
}

.phone-info .phone-label {
  font-size: 1.02rem;
  /* 增大20% */
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.phone-info .phone-number {
  font-size: 1.2rem;
  font-weight: 600;
  color: white;
  word-break: break-all;
}

.phone-action-btn {
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: white;
  border-radius: 8px;
  padding: 0.5rem;
  cursor: pointer;
  transition: all 0.2s ease;
  backdrop-filter: blur(10px);
  flex-shrink: 0;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 确保在所有平台上都能正常触发拨号 */
  -webkit-touch-callout: default;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.phone-action-btn:hover {
  background: rgba(255, 255, 255, 0.3);
  border-color: rgba(255, 255, 255, 0.5);
  transform: scale(1.05);
  color: white;
  text-decoration: none;
}

.phone-action-btn:active {
  transform: scale(0.95);
  color: white;
  text-decoration: none;
}

.phone-action-btn:focus {
  outline: none;
  color: white;
  text-decoration: none;
}

.phone-action-btn i {
  font-size: 1rem;
}

.phone-section {
  margin-bottom: 1rem;
}

.phone-item {
  margin-bottom: 0.75rem;
}

.phone-item:last-child {
  margin-bottom: 0;
}

.phone-label {
  font-size: 0.8rem;
  color: #6c757d;
  margin-bottom: 0.25rem;
}

.phone-number {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.1rem;
  font-weight: 600;
}

.phone-item.primary .phone-number {
  color: #007bff;
}

.phone-item.secondary .phone-number {
  color: #28a745;
}

.copy-btn {
  background: none;
  border: 1px solid currentColor;
  color: inherit;
  border-radius: 4px;
  padding: 0.25rem 0.5rem;
  font-size: 0.8rem;
  cursor: pointer;
}

.copy-btn-small {
  background: none;
  border: 1px solid currentColor;
  color: inherit;
  border-radius: 3px;
  padding: 0.15rem 0.3rem;
  font-size: 0.7rem;
  cursor: pointer;
  margin-left: 0.5rem;
  opacity: 0.7;
  transition: opacity 0.2s ease;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 确保在所有平台上都能正常触发拨号 */
  -webkit-touch-callout: default;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.copy-btn-small:hover {
  opacity: 1;
  color: inherit;
  text-decoration: none;
}

.copy-btn-small:active {
  transform: scale(0.95);
  color: inherit;
  text-decoration: none;
}

.copy-btn-small:focus {
  outline: none;
  color: inherit;
  text-decoration: none;
}

.basic-info {
  border-top: 1px solid #dee2e6;
  padding-top: 1rem;
}

.info-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

.info-label {
  color: #6c757d;
  min-width: 80px;
}

.info-value {
  color: #495057;
  text-align: right;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem;
}

.info-value.phone {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.25rem;
}

.phone-combined-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.phone-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1;
}

.phone-group .info-label {
  color: #6c757d;
  white-space: nowrap;
  flex-shrink: 0;
}

.phone-group .info-value {
  color: #495057;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-width: 0;
}

.info-value.amount {
  color: #28a745;
  font-weight: 600;
}

/* HIS余额 */
.his-balance {
  border-top: 1px solid #dee2e6;
  padding-top: 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.balance-label {
  font-size: 0.9rem;
  color: #6c757d;
}

.balance-value .loading {
  color: #6c757d;
  font-size: 0.9rem;
}

.balance-value .error {
  color: #dc3545;
  font-size: 0.9rem;
}

.balance-value .amount {
  font-size: 1.1rem;
  font-weight: 600;
}

.balance-value .amount.positive {
  color: #28a745;
}

.balance-value .amount.zero {
  color: #ffc107;
}

/* 快速指引 */
.quick-guide {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  overflow: hidden;
}

.guide-header {
  padding: 1rem;
  background: #f8f9fa;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  font-weight: 600;
  color: #495057;
}

.guide-content {
  padding: 1rem;
}

.guide-section {
  margin-bottom: 1rem;
}

.guide-section:last-child {
  margin-bottom: 0;
}

.guide-section h6 {
  font-size: 0.9rem;
  font-weight: 600;
  color: #495057;
  margin-bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.guide-section h6 i {
  font-size: 1rem;
}

/* 术语样式 */
.terms-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.term-item {
  background: #f8f9fa;
  border-radius: 6px;
  padding: 0.75rem;
  border-left: 3px solid #007bff;
}

.term-title {
  font-weight: 600;
  color: #495057;
  margin-bottom: 0.25rem;
  font-size: 0.85rem;
}

.term-content {
  color: #6c757d;
  line-height: 1.4;
  font-size: 0.8rem;
}

/* 话术分类样式 */
.scripts-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.script-category {
  margin-bottom: 0.5rem;
}

.category-title {
  font-weight: 600;
  color: #495057;
  margin-bottom: 0.5rem;
  padding: 0.5rem 0.75rem;
  background: #e9ecef;
  border-radius: 6px;
  border-left: 3px solid #28a745;
  font-size: 0.85rem;
}

.script-items {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.script-item {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.script-item:hover {
  background: #e9ecef;
  border-color: #28a745;
  transform: translateY(-1px);
}

.script-item:active {
  transform: translateY(0);
  background: #dee2e6;
}

.script-item i {
  color: #28a745;
  font-size: 0.75rem;
  flex-shrink: 0;
}

/* 注意事项样式 */
.note-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.note-item {
  font-size: 0.8rem;
  color: #6c757d;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  line-height: 1.4;
}

.note-item i {
  color: #28a745;
  margin-top: 0.1rem;
  flex-shrink: 0;
  font-size: 0.75rem;
}

/* 详情加载状态 */
.detail-loading {
  text-align: center;
  padding: 2rem;
  color: #6c757d;
}

.detail-empty {
  text-align: center;
  padding: 2rem;
  color: #6c757d;
}

/* 响应式调整 */
@media (max-width: 576px) {
  .mobile-content {
    padding: 0.75rem;
  }

  .task-stats {
    gap: 0.5rem;
  }

  .detail-stats {
    gap: 0.5rem;
  }

  .stat-card {
    padding: 0.75rem;
  }

  .stat-number {
    font-size: 1.25rem;
  }

  /* 头部导航响应式优化 */
  .modal-header {
    padding: 0.75rem;
    gap: 0.75rem;
  }

  .title-navigation-row {
    justify-content: space-between;
    height: 36px;
    /* 小屏幕下稍微减小高度 */
    position: relative;
  }

  .header-left {
    gap: 0.375rem;
  }

  .modal-title {
    font-size: 1.2rem;
    /* 增大20% */
    height: 36px;
    /* 与导航组统一高度 */
    max-width: calc(100% - 100px);
    /* 为导航按钮组留出空间 */
  }

  .header-navigation {
    padding: 0.2rem 0.4rem;
    gap: 0.2rem;
    height: 36px;
    /* 与标题统一高度 */
    position: absolute;
    right: 0;
    top: 0;
  }

  .nav-btn-header {
    min-width: 24px;
    height: 24px;
    padding: 0.2rem 0.4rem;
    font-size: 0.7rem;
  }

  .nav-info-header {
    font-size: 0.7rem;
    padding: 0 0.375rem;
  }

  .modal-close {
    width: 36px;
    height: 36px;
    font-size: 1.1rem;
  }
}

/* 深色模式支持 */
/* 深色模式样式 - 支持系统级别和应用级别 */
@media (prefers-color-scheme: dark) {
  .mobile-refund-task {
    background: #121212;
    color: #ffffff;
  }
}

#app.dark-mode .mobile-refund-task {
  background: #121212;
  color: #ffffff;
}

#app.dark-mode .mobile-header {
  background: linear-gradient(135deg, #1a1a1a, #2a2a2a);
  color: #e3f2fd;
  border-bottom-color: #444;
  padding: 0.32rem;
  padding-top: calc(0.32rem + env(safe-area-inset-top));
}

#app.dark-mode .header-title {
  color: #90caf9;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  font-size: 1.05rem;
  line-height: 1.2;
}

#app.dark-mode .header-actions .btn {
  border-color: #64b5f6;
  color: #64b5f6;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
  width: 32px;
  height: 24px;
  font-size: 0.85rem;
}

#app.dark-mode .header-actions .btn:hover {
  background: #64b5f6;
  color: #000;
  border-color: #64b5f6;
}

#app.dark-mode .stat-item,
#app.dark-mode .stat-card {
  background: #2a2a2a;
}

#app.dark-mode .stat-number {
  color: #ffffff !important;
}

/* 深色模式下的header样式 */
@media (prefers-color-scheme: dark) {
  .mobile-header {
    background: linear-gradient(135deg, #1a1a1a, #2a2a2a);
    color: #e3f2fd;
    border-bottom-color: #444;
    padding: 0.32rem;
    padding-top: calc(0.32rem + env(safe-area-inset-top));
  }

  .header-title {
    color: #90caf9;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 32px;
  }

  .header-actions .btn {
    border-color: #64b5f6;
    color: #64b5f6;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 6px;
    width: 32px;
    height: 24px;
    font-size: 0.85rem;
  }

  .header-actions .btn:hover {
    background: #64b5f6;
    color: #000;
    border-color: #64b5f6;
  }

  .task-card,
  .modal-content,
  .contact-info-card {
    background: #2a2a2a !important;
    border-color: #444 !important;
    color: #e0e0e0 !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
  }

  .patient-card {
    background: #374151 !important;
    border-color: #6b7280 !important;
    color: #f3f4f6 !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;
  }

  .patient-card:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4) !important;
    border-color: #4299e1 !important;
  }

  .patient-card.uncontacted {
    background: #2a1d49 !important;
    border-left-color: #585447 !important;
  }

  .patient-name {
    color: #e3f2fd !important;
  }

  .patient-name i {
    color: #64b5f6 !important;
  }

  .patient-contact-count span {
    background: #4299e1 !important;
    color: white !important;
  }

  .detail-label {
    color: #9e9e9e !important;
  }

  .detail-value {
    color: #e0e0e0 !important;
  }

  .detail-value.phone {
    color: #64b5f6 !important;
  }

  .detail-value.amount {
    color: #4caf50 !important;
  }

  .contact-status {
    border-top-color: #444 !important;
  }

  .status-contacted {
    color: #4caf50 !important;
  }

  .status-uncontacted {
    color: #9e9e9e !important;
  }

  .quick-guide {
    background: #1e1e1e;
    border-color: #333;
  }

  .stat-item,
  .stat-card {
    background: #2a2a2a;
  }

  .stat-number {
    color: #ffffff !important;
  }

  .patient-card.uncontacted {
    background: #2a2a1a;
    border-left-color: #ffc107;
  }

  /* 患者姓名在深色模式下的颜色 */
  .patient-name {
    color: #ffffff !important;
  }

  .modal-title {
    color: #ffffff !important;
  }

  .modal-header {
    background: #1e1e1e;
    border-bottom-color: #333;
  }

  .modal-header .modal-title {
    color: #ffffff !important;
  }

  .phone-info .phone-label {
    color: rgba(255, 255, 255, 0.9) !important;
  }

  /* 核心信息区域深色模式 */
  .fixed-info-section {
    background: #1e1e1e;
    border-bottom-color: #333;
  }

  .core-info-item {
    background: #2a2a2a;
    color: #ffffff;
  }

  .core-info-label {
    color: rgba(255, 255, 255, 0.7);
  }

  .core-info-value {
    color: #ffffff;
  }

  /* 性别、年龄、身份证等核心信息标签和值 */
  .core-label {
    color: rgba(255, 255, 255, 0.8) !important;
  }

  .core-value {
    color: #ffffff !important;
  }

  .age-info {
    color: #ffc107 !important;
  }

  .scrollable-content {
    background: #121212;
  }

  /* 深色模式下的下拉菜单样式 - 柔和优雅设计 */
  .contact-result-select {
    background-color: rgba(45, 45, 45, 0.95) !important;
    color: #d4d4d4 !important;
    border: 1px solid rgba(255, 255, 255, 0.15) !important;
    background-image: linear-gradient(45deg, transparent 50%, #d4d4d4 50%), linear-gradient(135deg, #d4d4d4 50%, transparent 50%) !important;
    background-position: calc(100% - 20px) calc(1em + 2px), calc(100% - 15px) calc(1em + 2px) !important;
    background-size: 5px 5px, 5px 5px !important;
    background-repeat: no-repeat !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
    transition: all 0.2s ease !important;
  }

  .contact-result-select option {
    background-color: rgba(45, 45, 45, 0.95) !important;
    color: #d4d4d4 !important;
  }

  .contact-result-select:focus {
    border-color: rgba(100, 149, 237, 0.6) !important;
    box-shadow: 0 0 0 3px rgba(100, 149, 237, 0.2), 0 4px 12px rgba(0, 0, 0, 0.4) !important;
    background-color: rgba(55, 55, 55, 0.95) !important;
    outline: none !important;
  }

  .contact-result-select:hover {
    background-color: rgba(55, 55, 55, 0.95) !important;
    border-color: rgba(255, 255, 255, 0.25) !important;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4) !important;
  }

  /* 联系结果选择器容器 */
  .contact-result-selector {
    background: rgba(40, 40, 40, 0.9) !important;
    border: 1px solid rgba(255, 255, 255, 0.1) !important;
    backdrop-filter: blur(8px) !important;
  }

  .result-select-container {
    background: rgba(35, 35, 35, 0.95) !important;
    backdrop-filter: blur(12px) !important;
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5) !important;
  }
}

/* 针对iOS的特殊处理 */
#app.dark-mode .mobile-refund-task {

  /* 深色模式下的header样式 */
  .mobile-header {
    background: linear-gradient(135deg, #1a1a1a, #2a2a2a);
    color: #e3f2fd;
    border-bottom-color: #444;
    padding: 0.32rem;
    padding-top: calc(0.32rem + env(safe-area-inset-top));
  }

  .header-title {
    color: #90caf9;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: 32px;
  }

  .header-actions .btn {
    border-color: #64b5f6;
    color: #64b5f6;
    background: rgba(0, 0, 0, 0.3);
    border-radius: 6px;
    width: 32px;
    height: 24px;
    font-size: 0.85rem;
  }

  .header-actions .btn:hover {
    background: #64b5f6;
    color: #000;
    border-color: #64b5f6;
  }

  .task-card,
  .modal-content,
  .contact-info-card,
  .quick-guide {
    background: #1e1e1e;
    border-color: #333;
  }

  .stat-item,
  .stat-card {
    background: #2a2a2a;
  }

  .patient-card.uncontacted {
    background: #2a2a1a;
    border-left-color: #ffc107;
  }

  /* 患者姓名在深色模式下的颜色 */
  .patient-name {
    color: #ffffff !important;
  }

  .modal-title {
    color: #ffffff !important;
  }

  .modal-header {
    background: #1e1e1e;
    border-bottom-color: #333;
  }

  .modal-header .modal-title {
    color: #ffffff !important;
  }

  .phone-info .phone-label {
    color: rgba(255, 255, 255, 0.9) !important;
  }

  /* 核心信息区域深色模式 */
  .fixed-info-section {
    background: #1e1e1e;
    border-bottom-color: #333;
  }

  .core-info-item {
    background: #2a2a2a;
    color: #ffffff;
  }

  .core-info-label {
    color: rgba(255, 255, 255, 0.7);
  }

  .core-info-value {
    color: #ffffff;
  }

  /* 性别、年龄、身份证等核心信息标签和值 */
  .core-label {
    color: rgba(255, 255, 255, 0.8) !important;
  }

  .core-value {
    color: #ffffff !important;
  }

  .age-info {
    color: #ffc107 !important;
  }

  .scrollable-content {
    background: #121212;
  }

  /* 深色模式下的下拉菜单样式 - 柔和优雅设计 */
  .contact-result-select {
    background-color: rgba(45, 45, 45, 0.95) !important;
    color: #d4d4d4 !important;
    border: 1px solid rgba(255, 255, 255, 0.15) !important;
    background-image: linear-gradient(45deg, transparent 50%, #d4d4d4 50%), linear-gradient(135deg, #d4d4d4 50%, transparent 50%) !important;
    background-position: calc(100% - 20px) calc(1em + 2px), calc(100% - 15px) calc(1em + 2px) !important;
    background-size: 5px 5px, 5px 5px !important;
    background-repeat: no-repeat !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
    transition: all 0.2s ease !important;
  }

  .contact-result-select option {
    background-color: rgba(45, 45, 45, 0.95) !important;
    color: #d4d4d4 !important;
  }

  .contact-result-select:focus {
    border-color: rgba(100, 149, 237, 0.6) !important;
    box-shadow: 0 0 0 3px rgba(100, 149, 237, 0.2), 0 4px 12px rgba(0, 0, 0, 0.4) !important;
    background-color: rgba(55, 55, 55, 0.95) !important;
    outline: none !important;
  }

  .contact-result-select:hover {
    background-color: rgba(55, 55, 55, 0.95) !important;
    border-color: rgba(255, 255, 255, 0.25) !important;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4) !important;
  }

  /* 联系结果选择器容器 */
  .contact-result-selector {
    background: rgba(40, 40, 40, 0.9) !important;
    border: 1px solid rgba(255, 255, 255, 0.1) !important;
    backdrop-filter: blur(8px) !important;
  }

  .result-select-container {
    background: rgba(35, 35, 35, 0.95) !important;
    backdrop-filter: blur(12px) !important;
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5) !important;
  }
}

/* 固定信息区域和可滚动内容样式 */
.contact-record-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.fixed-info-section {
  position: sticky;
  top: 0;
  z-index: 10;
  background: white;
  border-bottom: 2px solid #e9ecef;
  padding: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.core-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 1rem;
}

.core-info-item {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 0.75rem;
  text-align: center;
  border-left: 4px solid #007bff;
}

.core-info-item.gender {
  border-left-color: #28a745;
}

.core-info-item.id-card {
  border-left-color: #ffc107;
}

.core-info-item.balance {
  border-left-color: #dc3545;
}

.core-info-label {
  font-size: 0.8rem;
  color: #6c757d;
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.core-info-value {
  font-size: 1rem;
  font-weight: 600;
  color: #495057;
}

.core-info-value.amount {
  color: #28a745;
}

.scrollable-content {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  background: #f8f9fa;
}

.collapsible-card {
  background: white;
  border-radius: 12px;
  margin-bottom: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  transition: all 0.3s ease;
}

.collapsible-header {
  padding: 1rem;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  border-bottom: 1px solid #dee2e6;
  transition: all 0.2s ease;
}

.collapsible-header:hover {
  background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
}

.collapsible-header:active {
  transform: scale(0.98);
}

.collapsible-title {
  font-weight: 600;
  color: #495057;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.collapsible-title i {
  color: #007bff;
}

.collapse-icon {
  transition: transform 0.3s ease;
  color: #6c757d;
}

.collapse-icon.expanded {
  transform: rotate(180deg);
}

.collapsible-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.collapsible-content.expanded {
  max-height: 1000px;
}

.collapsible-body {
  padding: 1rem;
}

/* 响应式调整 */
@media (max-width: 576px) {
  .core-info-grid {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }

  .fixed-info-section {
    padding: 0.75rem;
  }

  .scrollable-content {
    padding: 0.75rem;
  }

  .collapsible-header {
    padding: 0.75rem;
  }

  .collapsible-body {
    padding: 0.75rem;
  }
}

/* 新增的核心信息区域样式 */
.core-info-card {
  margin-bottom: 1rem;
}

.core-basic-info {
  margin-bottom: 1rem;
}

.core-basic-info .core-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: 0;
}

.core-basic-info .core-info-item {
  background: #f8f9fa;
  border-radius: 6px;
  padding: 0.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-left: 3px solid #007bff;
}

.core-label {
  font-size: 0.8rem;
  color: #6c757d;
  font-weight: 500;
}

.core-value {
  font-size: 0.9rem;
  font-weight: 600;
  color: #495057;
}

.core-his-balance {
  background: linear-gradient(135deg, #e8f5e8 0%, #f0f8f0 100%);
  border-radius: 8px;
  padding: 0.75rem;
  border-left: 4px solid #28a745;
}

.balance-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.balance-title {
  font-size: 0.9rem;
  font-weight: 600;
  color: #495057;
}

.balance-content .loading {
  color: #6c757d;
  font-size: 0.9rem;
}

.balance-content .error {
  color: #dc3545;
  font-size: 0.9rem;
}

.balance-content .amount {
  font-size: 1.1rem;
  font-weight: 700;
}

.balance-content .amount.positive {
  color: #28a745;
}

.balance-content .amount.zero {
  color: #ffc107;
}

/* 余额变动查询按钮样式 */
.balance-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
  gap: 0.5rem;
}

.balance-title-section {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.refund-query-btn {
  padding: 0.375rem 0.75rem;
  font-size: 0.8rem;
  font-weight: 600;
  border: none;
  border-radius: 20px;
  background: linear-gradient(135deg, #007bff, #0056b3);
  color: white;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
  display: flex;
  align-items: center;
  gap: 0.375rem;
  white-space: nowrap;
  flex-shrink: 0;
}

.refund-query-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.4);
  background: linear-gradient(135deg, #0056b3, #004085);
}

.refund-query-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(0, 123, 255, 0.3);
}

.refund-query-btn i {
  font-size: 0.75rem;
}

/* 深色模式按钮样式 */
@media (prefers-color-scheme: dark),
#app.dark-mode {
  .refund-query-btn {
    background: linear-gradient(135deg, #0066cc, #004499);
    color: white;
    box-shadow: 0 2px 8px rgba(0, 102, 204, 0.4);
  }

  .refund-query-btn:hover {
    background: linear-gradient(135deg, #0080ff, #0066cc);
    box-shadow: 0 4px 12px rgba(0, 128, 255, 0.5);
  }

  .refund-query-btn:active {
    box-shadow: 0 2px 6px rgba(0, 102, 204, 0.4);
  }
}

/* 移动端适配 */
@media (max-width: 576px) {
  .balance-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .refund-query-btn {
    padding: 0.3125rem 0.625rem;
    font-size: 0.75rem;
    margin-left: 0.5rem;
    width: auto;
    margin-top: 0;
  }
}

@media (max-width: 480px) {
  .balance-header {
    gap: 0.375rem;
  }

  .balance-title-section {
    gap: 0.375rem;
  }

  .balance-title {
    font-size: 0.85rem;
  }

  .refund-query-btn {
    font-size: 0.7rem;
    padding: 0.25rem 0.5rem;
  }
}

@media (max-width: 400px) {
  .refund-query-btn {
    font-size: 0.65rem;
    padding: 0.2rem 0.4rem;
  }
  
  .refund-query-btn i {
    display: none;
  }
}

/* 折叠卡片样式 */
.card-header {
  padding: 1rem;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  border-bottom: 1px solid #dee2e6;
  transition: all 0.2s ease;
}

.card-header:hover {
  background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
}

.header-content {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: #495057;
}

.header-content i {
  color: #007bff;
}

.card-content {
  padding: 1rem;
}

.detail-info-grid {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.detail-info-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0;
  border-bottom: 1px solid #f0f0f0;
}

.detail-info-row:last-child {
  border-bottom: none;
}

.detail-label {
  font-size: 0.9rem;
  color: #6c757d;
  font-weight: 500;
  min-width: 80px;
}

.detail-value {
  font-size: 0.9rem;
  color: #495057;
  font-weight: 600;
  text-align: right;
  flex: 1;
}

.detail-value.phone {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  justify-content: flex-end;
}

.detail-value.amount {
  color: #28a745;
}

/* 联系记录表单样式 */
.contact-records-section {
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.section-header {
  padding: 1rem;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-bottom: 1px solid #dee2e6;
}

.section-header h6 {
  margin: 0;
  font-weight: 600;
  color: #495057;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.contact-modal .header-actions {
  margin-top: 0.75rem;
}

.action-buttons {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

.navigation-group {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.nav-btn {
  width: 28px;
  height: 28px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.nav-info {
  font-size: 0.75rem;
  color: #6c757d;
  font-weight: 500;
  min-width: 50px;
  text-align: center;
}

.save-btn {
  white-space: nowrap;
}

/* 单个联系记录保存相关样式 */
.record-save-section {
  margin-top: 1rem;
  padding: 0.5rem;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.record-save-btn {
  width: 100%;
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.record-save-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.record-save-btn:not(:disabled):hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(40, 167, 69, 0.3);
}

/* 响应式调整 */
@media (max-width: 576px) {
  .record-save-section {
    padding: 0.4rem;
  }

  .record-save-btn {
    font-size: 0.85rem;
    padding: 0.4rem 0.8rem;
  }

  .next-record-prompt {
    margin: 0.5rem;
  }

  .prompt-actions {
    flex-direction: column;
    gap: 0.5rem;
  }

  .prompt-actions .btn {
    width: 100%;
  }
}

/* 跳转下一条记录提示样式 */
.next-record-prompt {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1050;
  background: white;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  border: 1px solid #e9ecef;
  animation: promptSlideIn 0.3s ease-out;
  max-width: 90vw;
  width: 320px;
}

@keyframes promptSlideIn {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.9);
  }

  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

.prompt-content {
  padding: 1.5rem;
}

.prompt-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.prompt-header i {
  font-size: 1.5rem;
}

.prompt-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: #495057;
}

.prompt-message {
  color: #6c757d;
  margin-bottom: 1.5rem;
  font-size: 0.95rem;
  line-height: 1.4;
}

.prompt-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
}

.prompt-actions .btn {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  font-weight: 600;
  border-radius: 6px;
  min-width: 100px;
  transition: all 0.2s ease;
}

.prompt-actions .btn-primary {
  background: linear-gradient(135deg, #007bff, #0056b3);
  border: none;
  box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
}

.prompt-actions .btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.4);
}

.prompt-actions .btn-outline-secondary {
  border-color: #6c757d;
  color: #6c757d;
}

.prompt-actions .btn-outline-secondary:hover {
  background: #6c757d;
  border-color: #6c757d;
  color: white;
}

/* 年龄信息样式 */
.age-info {
  color: #6c757d;
  font-size: 0.9em;
  font-weight: bold;
}

/* 电话按钮禁用状态样式 */
.phone-action-btn.disabled,
.copy-btn-small.disabled {
  background: #f8f9fa !important;
  color: #6c757d !important;
  border-color: #e9ecef !important;
  cursor: not-allowed !important;
  opacity: 0.6;
  pointer-events: none;
}

.phone-action-btn.disabled:hover,
.copy-btn-small.disabled:hover {
  background: #f8f9fa !important;
  color: #6c757d !important;
  transform: none !important;
  box-shadow: none !important;
}

/* 创建任务弹窗样式 */
.create-task-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1050;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
  padding: 1rem;
}

.create-task-modal.show {
  opacity: 1;
  visibility: visible;
}

.create-task-modal .modal-content {
  background: white;
  border-radius: 12px;
  width: 100%;
  max-width: 400px;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  transform: translateY(20px);
  transition: transform 0.3s ease;
}

.create-task-modal.show .modal-content {
  transform: translateY(0);
}

.create-task-modal .modal-header {
  padding: 1.5rem 1.5rem 1rem;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.create-task-modal .modal-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: #495057;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.create-task-modal .modal-title i {
  color: #007bff;
  font-size: 1.3rem;
}

.create-task-modal .btn-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  color: #6c757d;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: all 0.2s ease;
}

.create-task-modal .btn-close:hover {
  background: #f8f9fa;
  color: #495057;
}

.create-task-modal .modal-body {
  padding: 1.5rem;
}

.create-task-modal .form-group {
  margin-bottom: 1.5rem;
}

.create-task-modal .form-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: #495057;
  margin-bottom: 1rem;
  font-size: 1rem;
}

.create-task-modal .form-label i {
  color: #007bff;
  font-size: 1.1rem;
}

.quantity-selector {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 1.5rem;
}

.quantity-display {
  text-align: center;
  margin-bottom: 1.5rem;
}

.quantity-value {
  font-size: 2rem;
  font-weight: 700;
  color: #007bff;
  display: block;
}

.quantity-unit {
  font-size: 0.9rem;
  color: #6c757d;
  margin-top: 0.25rem;
}

.quantity-slider {
  position: relative;
}

.slider {
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: #dee2e6;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #007bff;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 123, 255, 0.3);
  transition: all 0.2s ease;
}

.slider::-webkit-slider-thumb:hover {
  transform: scale(1.1);
  box-shadow: 0 3px 8px rgba(0, 123, 255, 0.4);
}

.slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #007bff;
  cursor: pointer;
  border: none;
  box-shadow: 0 2px 6px rgba(0, 123, 255, 0.3);
}

.slider-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 0.5rem;
  font-size: 0.8rem;
  color: #6c757d;
}

.limit-info {
  margin-top: 1.5rem;
}

.limit-info .alert {
  padding: 1rem;
  border-radius: 8px;
  border: none;
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.limit-info .alert:last-child {
  margin-bottom: 0;
}

.limit-info .alert i {
  font-size: 1.1rem;
  margin-top: 0.1rem;
  flex-shrink: 0;
}

.limit-info .alert-info {
  background: #e7f3ff;
  color: #0c5460;
}

.limit-info .alert-info i {
  color: #0dcaf0;
}

.limit-info .alert-warning {
  background: #fff3cd;
  color: #664d03;
}

.limit-info .alert-warning i {
  color: #ffc107;
}

.create-task-modal .modal-footer {
  padding: 1rem 1.5rem 1.5rem;
  border-top: 1px solid #e9ecef;
  display: flex;
  gap: 1rem;
  justify-content: flex-end;
}

.create-task-modal .modal-footer .btn {
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: all 0.2s ease;
  min-width: 100px;
  justify-content: center;
}

.create-task-modal .modal-footer .btn-primary {
  background: linear-gradient(135deg, #007bff, #0056b3);
  border: none;
  box-shadow: 0 2px 8px rgba(0, 123, 255, 0.3);
}

.create-task-modal .modal-footer .btn-primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 123, 255, 0.4);
}

.create-task-modal .modal-footer .btn-primary:disabled {
  background: #6c757d;
  opacity: 0.6;
  cursor: not-allowed;
}

.create-task-modal .modal-footer .btn-outline-secondary {
  border-color: #6c757d;
  color: #6c757d;
  background: transparent;
}

.create-task-modal .modal-footer .btn-outline-secondary:hover {
  background: #6c757d;
  border-color: #6c757d;
  color: white;
}

/* 坐席账号统计样式 */
.agent-stats-section {
  margin: 12px 0;
  background: #f8f9fa;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid #e9ecef;
}

.agent-stats-toggle {
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  transition: all 0.3s ease;
}

.agent-stats-toggle:hover {
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.toggle-content {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
}

.toggle-content i {
  font-size: 18px;
}

.toggle-text {
  font-weight: 500;
  font-size: 15px;
}

.quick-stats {
  display: flex;
  gap: 8px;
  margin-left: auto;
  margin-right: 12px;
}

.stat-badge {
  background: rgba(255, 255, 255, 0.2);
  color: white;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  min-width: 24px;
  text-align: center;
  backdrop-filter: blur(10px);
}

.stat-badge.available {
  background: rgba(40, 167, 69, 0.8);
}

.stat-badge.in-use {
  background: rgba(255, 193, 7, 0.8);
}

.toggle-icon {
  font-size: 16px;
  transition: transform 0.3s ease;
}

.agent-stats-content {
  padding: 16px;
  background: white;
}

.stats-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  color: #6c757d;
}

.spinner-small {
  width: 16px;
  height: 16px;
  border: 2px solid #e9ecef;
  border-top: 2px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin-bottom: 12px;
}

.stat-card {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: all 0.3s ease;
  border: 1px solid #e9ecef;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.stat-card.available {
  border-left: 4px solid #28a745;
}

.stat-card.available .stat-icon {
  color: #28a745;
}

.stat-card.in-use {
  border-left: 4px solid #ffc107;
}

.stat-card.in-use .stat-icon {
  color: #ffc107;
}

.stat-card.pending {
  border-left: 4px solid #17a2b8;
}

.stat-card.pending .stat-icon {
  color: #17a2b8;
}

.stat-card.total {
  border-left: 4px solid #6f42c1;
}

.stat-card.total .stat-icon {
  color: #6f42c1;
}

.stat-icon {
  font-size: 20px;
  flex-shrink: 0;
}

.stat-info {
  flex: 1;
}

.stat-number {
  font-size: 18px;
  font-weight: 700;
  color: #212529;
  line-height: 1;
}

.stat-label {
  font-size: 12px;
  color: #6c757d;
  margin-top: 2px;
}

.stats-footer {
  border-top: 1px solid #e9ecef;
  padding-top: 12px;
  margin-top: 12px;
}

.update-time {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #6c757d;
  justify-content: center;
}

.update-time i {
  font-size: 12px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

/* 移动端适配 */
@media (max-width: 576px) {
  .create-task-modal {
    padding: 0.5rem;
  }

  .create-task-modal .modal-content {
    max-width: none;
    width: 100%;
  }

  .create-task-modal .modal-header,
  .create-task-modal .modal-body,
  .create-task-modal .modal-footer {
    padding-left: 1rem;
    padding-right: 1rem;
  }

  .create-task-modal .modal-footer {
    flex-direction: column;
  }

  .create-task-modal .modal-footer .btn {
    width: 100%;
  }

  /* 坐席统计移动端适配 */
  .stats-grid {
    grid-template-columns: 1fr;
  }

  .quick-stats {
    margin-left: 8px;
    margin-right: 8px;
  }

  .agent-stats-toggle {
    padding: 10px 12px;
  }

  .toggle-content {
    gap: 8px;
  }

  .toggle-text {
    font-size: 14px;
  }
}

/* 自定义确认对话框样式 - 黄金分割设计 */
.confirm-dialog {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.confirm-dialog .modal-content {
  /* 黄金分割比例：屏幕宽度的61.8% */
  width: 61.8vw;
  max-width: 480px;
  min-width: 320px;
  /* 控制高度占屏幕40% */
  max-height: 40vh;
  margin: 0;
  /* 垂直居中，稍微偏上（黄金分割点） */
  margin-top: -8vh;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 8px 20px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
  animation: confirmDialogSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  display: flex;
  flex-direction: column;
}

@keyframes confirmDialogSlideIn {
  from {
    opacity: 0;
    transform: translateY(-30px) scale(0.9);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.confirm-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-bottom: none;
  padding: 1rem 1.5rem 0.75rem;
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

.confirm-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.1) 100%);
  pointer-events: none;
}

.confirm-title {
  color: #ffffff;
  font-size: 1.4rem;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  position: relative;
  z-index: 1;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.confirm-title i {
  color: #ffd700;
  font-size: 1.6rem;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.confirm-body {
  padding: 1.25rem 1.5rem;
  background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%);
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.confirm-message {
  color: #2c3e50;
  font-size: 1.5rem;
  line-height: 1.5;
  white-space: pre-line;
  text-align: center;
  font-weight: 600;
  letter-spacing: 0.5px;
  margin: 0;
}

.confirm-footer {
  padding: 1rem 1.5rem 1.25rem;
  display: flex;
  gap: 1rem;
  justify-content: center;
  border-top: none;
  background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
  flex-shrink: 0;
}

.confirm-footer .btn {
  min-width: 120px;
  padding: 0.75rem 1.5rem;
  font-weight: 700;
  font-size: 1.1rem;
  border-radius: 25px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border: 2px solid transparent;
  position: relative;
  overflow: hidden;
}

.confirm-footer .btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transition: left 0.5s;
}

.confirm-footer .btn:hover::before {
  left: 100%;
}

.confirm-footer .btn-secondary {
  background: linear-gradient(135deg, #6c757d, #5a6268);
  color: #ffffff;
  border: 2px solid #495057;
  box-shadow: 0 4px 15px rgba(108, 117, 125, 0.4);
  font-weight: 700;
}

.confirm-footer .btn-secondary:hover {
  transform: translateY(-2px);
  background: linear-gradient(135deg, #7c8691, #6a7278);
  border-color: #343a40;
  box-shadow: 0 6px 20px rgba(108, 117, 125, 0.5);
}

.confirm-footer .btn-primary {
  background: linear-gradient(135deg, #007bff, #0056b3);
  color: white;
  box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3);
}

.confirm-footer .btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 123, 255, 0.4);
}

/* 深色模式下的确认对话框样式 */
@media (prefers-color-scheme: dark),
#app.dark-mode {
  .confirm-dialog .modal-content {
    border-color: rgba(255, 255, 255, 0.1);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), 0 8px 20px rgba(0, 0, 0, 0.3);
  }

  .confirm-header {
    background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);
  }

  .confirm-title {
    color: #ffffff;
  }

  .confirm-title i {
    color: #ffd700;
  }

  .confirm-body {
    background: linear-gradient(180deg, #2d3748 0%, #1a202c 100%);
  }

  .confirm-message {
    color: #ffffff;
    font-size: 1.5rem;
    font-weight: 600;
  }

  .confirm-footer .btn-secondary {
    background: linear-gradient(135deg, #6b7280, #4b5563);
    color: #ffffff;
    box-shadow: 0 4px 15px rgba(107, 114, 128, 0.4);
  }

  .confirm-footer .btn-secondary:hover {
    background: linear-gradient(135deg, #7c8491, #5a6169);
    box-shadow: 0 6px 20px rgba(107, 114, 128, 0.5);
  }

  .confirm-footer {
    background: linear-gradient(180deg, #1a202c 0%, #171923 100%);
  }

  .confirm-footer .btn-secondary {
    background: linear-gradient(135deg, #4a5568, #2d3748);
    color: #ffffff;
    border: 2px solid #718096;
    box-shadow: 0 4px 15px rgba(74, 85, 104, 0.5);
    font-weight: 700;
  }

  .confirm-footer .btn-secondary:hover {
    background: linear-gradient(135deg, #5a6578, #3d4758);
    border-color: #a0aec0;
    box-shadow: 0 6px 20px rgba(74, 85, 104, 0.6);
  }

  .confirm-footer .btn-primary {
    background: linear-gradient(135deg, #3182ce, #2c5282);
    box-shadow: 0 4px 15px rgba(49, 130, 206, 0.4);
  }

  .confirm-footer .btn-primary:hover {
    box-shadow: 0 6px 20px rgba(49, 130, 206, 0.5);
  }
}

/* 移动端确认对话框适配 */
@media (max-width: 768px) {
  .confirm-dialog .modal-content {
    /* 移动端使用更大的黄金分割比例 */
    width: 85vw;
    max-width: none;
    max-height: 42vh;
    margin-top: -5vh;
  }

  .confirm-header {
    padding: 0.875rem 1.25rem 0.625rem;
  }

  .confirm-title {
    font-size: 1.2rem;
  }

  .confirm-title i {
    font-size: 1.3rem;
  }

  .confirm-body {
    padding: 1rem 1.25rem;
  }

  .confirm-message {
    font-size: 1.35rem;
  }

  .confirm-footer {
    padding: 1rem 1.25rem 1.125rem;
    flex-direction: column;
    gap: 0.75rem;
  }

  .confirm-footer .btn {
    width: 100%;
    min-width: auto;
  }
}

/* 超小屏幕适配 */
@media (max-width: 480px) {
  .confirm-dialog .modal-content {
    width: 95vw;
    max-height: 45vh;
    margin-top: -3vh;
  }

  .confirm-header {
    padding: 0.75rem 1rem 0.5rem;
  }

  .confirm-title {
    font-size: 1.1rem;
  }

  .confirm-body {
    padding: 0.875rem 1rem;
  }

  .confirm-message {
    font-size: 1.25rem;
  }

  .confirm-footer {
    padding: 0.875rem 1rem 1rem;
  }
}

/* 自定义输入对话框样式 - 基于确认对话框设计 */
.input-dialog {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.input-dialog .modal-content {
  /* 黄金分割比例：屏幕宽度的61.8% */
  width: 61.8vw;
  max-width: 480px;
  min-width: 320px;
  /* 控制高度占屏幕45% */
  max-height: 45vh;
  margin: 0;
  /* 垂直居中，稍微偏上（黄金分割点） */
  margin-top: -8vh;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15), 0 8px 20px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
  animation: inputDialogSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  display: flex;
  flex-direction: column;
}

@keyframes inputDialogSlideIn {
  from {
    opacity: 0;
    transform: translateY(-30px) scale(0.9);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.input-header {
  background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
  border-bottom: none;
  padding: 1rem 1.5rem 0.75rem;
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

.input-header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.1) 100%);
  pointer-events: none;
}

.input-title {
  color: #ffffff;
  font-size: 1.4rem;
  font-weight: 700;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  position: relative;
  z-index: 1;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.input-title i {
  color: #ffd700;
  font-size: 1.6rem;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.input-body {
  padding: 1.25rem 1.5rem;
  background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%);
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.input-message {
  color: #2c3e50;
  font-size: 1.1rem;
  line-height: 1.5;
  white-space: pre-line;
  text-align: center;
  font-weight: 500;
  letter-spacing: 0.3px;
  margin: 0;
}

.input-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.input-control {
  width: 100%;
  padding: 0.875rem 1rem;
  font-size: 1.1rem;
  border: 2px solid #e9ecef;
  border-radius: 12px;
  background: #ffffff;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  font-weight: 500;
}

.input-control:focus {
  outline: none;
  border-color: #28a745;
  box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.1), 0 4px 12px rgba(0, 0, 0, 0.1);
  background: #ffffff;
}

.input-control::placeholder {
  color: #6c757d;
  font-weight: 400;
}

.input-footer {
  padding: 1rem 1.5rem 1.25rem;
  display: flex;
  gap: 1rem;
  justify-content: center;
  border-top: none;
  background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
  flex-shrink: 0;
}

.input-footer .btn {
  min-width: 120px;
  padding: 0.75rem 1.5rem;
  font-weight: 700;
  font-size: 1.1rem;
  border-radius: 25px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  border: 2px solid transparent;
  position: relative;
  overflow: hidden;
}

.input-footer .btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transition: left 0.5s;
}

.input-footer .btn:hover::before {
  left: 100%;
}

.input-footer .btn-secondary {
  background: linear-gradient(135deg, #6c757d, #5a6268);
  color: #ffffff;
  border: 2px solid #495057;
  box-shadow: 0 4px 15px rgba(108, 117, 125, 0.4);
  font-weight: 700;
}

.input-footer .btn-secondary:hover {
  transform: translateY(-2px);
  background: linear-gradient(135deg, #7c8691, #6a7278);
  border-color: #343a40;
  box-shadow: 0 6px 20px rgba(108, 117, 125, 0.5);
}

.input-footer .btn-primary {
  background: linear-gradient(135deg, #28a745, #20c997);
  color: white;
  box-shadow: 0 4px 15px rgba(40, 167, 69, 0.3);
}

.input-footer .btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(40, 167, 69, 0.4);
}

/* 深色模式下的输入对话框样式 */
@media (prefers-color-scheme: dark),
#app.dark-mode {
  .input-dialog .modal-content {
    border-color: rgba(255, 255, 255, 0.1);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), 0 8px 20px rgba(0, 0, 0, 0.3);
  }

  .input-header {
    background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);
  }

  .input-title {
    color: #ffffff;
  }

  .input-title i {
    color: #ffd700;
  }

  .input-body {
    background: linear-gradient(180deg, #2d3748 0%, #1a202c 100%);
  }

  .input-message {
    color: #ffffff;
    font-size: 1.1rem;
    font-weight: 500;
  }

  .input-control {
    background: #4a5568;
    border-color: #718096;
    color: #ffffff;
  }

  .input-control:focus {
    border-color: #68d391;
    box-shadow: 0 0 0 3px rgba(104, 211, 145, 0.1), 0 4px 12px rgba(0, 0, 0, 0.2);
    background: #4a5568;
  }

  .input-control::placeholder {
    color: #a0aec0;
  }

  .input-footer {
    background: linear-gradient(180deg, #1a202c 0%, #171923 100%);
  }

  .input-footer .btn-secondary {
    background: linear-gradient(135deg, #4a5568, #2d3748);
    color: #ffffff;
    border: 2px solid #718096;
    box-shadow: 0 4px 15px rgba(74, 85, 104, 0.5);
    font-weight: 700;
  }

  .input-footer .btn-secondary:hover {
    background: linear-gradient(135deg, #5a6578, #3d4758);
    border-color: #a0aec0;
    box-shadow: 0 6px 20px rgba(74, 85, 104, 0.6);
  }

  .input-footer .btn-primary {
    background: linear-gradient(135deg, #38a169, #2f855a);
    box-shadow: 0 4px 15px rgba(56, 161, 105, 0.4);
  }

  .input-footer .btn-primary:hover {
    box-shadow: 0 6px 20px rgba(56, 161, 105, 0.5);
  }
}

/* 输入对话框特殊定位 - 解决小屏幕兼容性问题 */
.input-dialog {
  /* 覆盖默认的 align-items: flex-end，改为居中显示 */
  align-items: center;
  justify-content: center;
  padding: 1rem;
  /* 确保在所有设备上都能正确显示 */
  min-height: 100vh;
  min-height: 100dvh; /* 动态视口高度，避免移动端地址栏影响 */
}

.input-dialog .modal-content {
  /* 覆盖默认的底部弹出样式 */
  transform: scale(0.9);
  border-radius: 16px;
  width: 90%;
  max-width: 400px;
  max-height: 65vh; /* 减少最大高度，为老设备留出更多空间 */
  margin: 0;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
  /* 确保内容不会溢出 */
  overflow: hidden;
  /* 添加最小高度确保内容可见 */
  min-height: 280px;
}

.input-dialog.show .modal-content {
  transform: scale(1);
}

/* 移动端输入对话框适配 */
@media (max-width: 768px) {
  .input-dialog {
    padding: 0.5rem;
    /* 确保在移动端有足够的安全区域 */
    padding-top: max(0.5rem, env(safe-area-inset-top));
    padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
  }

  .input-dialog .modal-content {
    width: 96%;
    max-width: none;
    max-height: 55vh; /* 进一步减少高度，确保在小屏幕上可见 */
    min-height: 260px; /* 确保最小高度 */
    /* 确保弹窗不会被系统UI遮挡 */
    margin-top: 0;
    margin-bottom: 0;
  }

  .input-header {
    padding: 0.75rem 1rem 0.5rem;
    /* 减少头部高度 */
    min-height: auto;
  }

  .input-title {
    font-size: 1.1rem;
    line-height: 1.3;
  }

  .input-title i {
    font-size: 1.2rem;
  }

  .input-body {
    padding: 0.875rem 1rem;
    /* 确保输入区域有足够空间 */
    flex: 1;
    min-height: 120px;
  }

  .input-message {
    font-size: 0.95rem;
    margin-bottom: 0.75rem;
  }

  .input-control {
    padding: 0.75rem;
    font-size: 1rem;
    /* 确保输入框有足够的点击区域 */
    min-height: 48px;
    border-radius: 8px;
  }

  .input-footer {
    padding: 0.75rem 1rem 1rem;
    flex-direction: column;
    gap: 0.5rem;
    /* 减少底部区域高度 */
    flex-shrink: 0;
  }

  .input-footer .btn {
    width: 100%;
    min-width: auto;
    padding: 0.75rem;
    font-size: 1rem;
  }
}

/* 超小屏幕适配 - iPhone 6等小屏设备 */
@media (max-width: 480px) {
  .input-dialog {
    padding: 0.25rem;
    /* 针对小屏幕设备的特殊处理 */
    padding-top: max(0.25rem, env(safe-area-inset-top));
    padding-bottom: max(0.25rem, env(safe-area-inset-bottom));
    /* 确保弹窗在视口中央 */
    align-items: center;
    justify-content: center;
  }

  .input-dialog .modal-content {
    width: 98%;
    max-height: 50vh;
    min-height: 240px; /* 确保在小屏幕上也有足够高度 */
    /* 针对nova2等老设备的特殊优化 */
    position: relative;
    top: 0;
    transform: none;
  }

  .input-dialog.show .modal-content {
    transform: none;
    animation: inputDialogFadeIn 0.3s ease-out;
  }

  .input-header {
    padding: 0.625rem 0.875rem 0.375rem;
    min-height: 50px; /* 固定头部高度 */
  }

  .input-title {
    font-size: 1rem;
    line-height: 1.2;
  }

  .input-title i {
    font-size: 1.1rem;
  }

  .input-body {
    padding: 0.75rem 0.875rem;
    /* 确保输入区域在小屏幕上可见 */
    flex: 1;
    min-height: 100px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .input-message {
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
    text-align: center;
  }

  .input-control {
    padding: 0.75rem;
    font-size: 1rem;
    /* 确保输入框在小屏幕上易于点击 */
    min-height: 44px;
    border-radius: 6px;
    /* 防止输入框被挤压 */
    flex-shrink: 0;
  }

  .input-footer {
    padding: 0.625rem 0.875rem 0.75rem;
    min-height: 80px; /* 固定底部高度 */
    flex-shrink: 0;
  }

  .input-footer .btn {
    padding: 0.625rem;
    font-size: 0.95rem;
    min-height: 44px; /* 确保按钮易于点击 */
  }
}

/* 极小屏幕适配 - 确保在所有设备上都可见 */
@media (max-width: 360px) {
  .input-dialog {
    padding: 0.125rem;
    /* 极小屏幕的安全区域处理 */
    padding-top: max(0.125rem, env(safe-area-inset-top));
    padding-bottom: max(0.125rem, env(safe-area-inset-bottom));
  }

  .input-dialog .modal-content {
    width: 99%;
    max-height: 45vh;
    min-height: 220px;
    /* 极小屏幕的特殊处理 */
    border-radius: 8px;
  }

  .input-header {
    padding: 0.5rem 0.75rem 0.25rem;
    min-height: 45px;
  }

  .input-title {
    font-size: 0.95rem;
    line-height: 1.1;
  }

  .input-title i {
    font-size: 1rem;
  }

  .input-body {
    padding: 0.625rem 0.75rem;
    min-height: 90px;
  }

  .input-message {
    font-size: 0.85rem;
    margin-bottom: 0.375rem;
  }

  .input-control {
    padding: 0.625rem 0.5rem;
    font-size: 0.95rem;
    min-height: 42px;
    border-radius: 4px;
  }

  .input-footer {
    padding: 0.5rem 0.75rem 0.625rem;
    min-height: 75px;
  }

  .input-footer .btn {
    padding: 0.5rem;
    font-size: 0.9rem;
    min-height: 42px;
  }
}

/* 添加淡入动画，替代缩放动画以提高兼容性 */
@keyframes inputDialogFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 针对老设备的额外优化 */
@media (max-width: 480px) and (max-height: 640px) {
  .input-dialog .modal-content {
    max-height: 45vh;
    min-height: 200px;
  }

  .input-body {
    min-height: 80px;
  }

  .input-footer {
    min-height: 70px;
  }
}

.input-message {
  font-size: 0.9rem;
}

.input-control {
  padding: 0.5rem 0.625rem;
  font-size: 0.9rem;
}

.input-footer {
  padding: 0.75rem 0.875rem 0.875rem;
}

.input-footer .btn {
  padding: 0.625rem 1rem;
  font-size: 0.95rem;
}

/* 退费申请查询弹窗样式 */
.refund-query-modal .modal-content {
  max-width: 600px;
  max-height: 80vh;
  overflow-y: auto;
}

.refund-query-modal .modal-body {
  padding: 0;
}

.refund-query-modal .detail-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  color: #6c757d;
}

.refund-query-modal .spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #e9ecef;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 1rem;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.refund-query-modal .empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  text-align: center;
}

.refund-query-modal .empty-icon {
  font-size: 3rem;
  color: #adb5bd;
  margin-bottom: 1rem;
}

.refund-query-modal .empty-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: #495057;
  margin-bottom: 0.5rem;
}

.refund-query-modal .empty-subtitle {
  color: #6c757d;
  font-size: 1rem;
}

.refund-list {
  padding: 1.5rem;
}

.refund-summary {
  margin-bottom: 1.5rem;
  padding: 1rem;
  background: linear-gradient(135deg, #f8f9fa, #e9ecef);
  border-radius: 12px;
  border-left: 4px solid #007bff;
}

.refund-summary .summary-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: #495057;
}

.refund-summary .summary-item i {
  color: #007bff;
}

.refund-items {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.refund-item-card {
  background: #ffffff;
  border: 1px solid #dee2e6;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.refund-item-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}

.refund-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid #e9ecef;
}

.refund-date {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #6c757d;
  font-size: 0.9rem;
}

.refund-status {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.375rem 0.75rem;
  border-radius: 20px;
  font-size: 0.8rem;
  font-weight: 600;
}

.refund-status.pending {
  background-color: #fff3cd;
  color: #856404;
}

.refund-status.approved {
  background-color: #d1edff;
  color: #0c5460;
}

.refund-status.rejected {
  background-color: #f8d7da;
  color: #721c24;
}

.refund-status.completed {
  background-color: #d4edda;
  color: #155724;
}

.refund-amount {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.75rem;
}

.refund-amount .amount-label {
  font-weight: 600;
  color: #495057;
}

.refund-amount .amount-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: #007bff;
}

.refund-description {
  color: #6c757d;
  font-size: 0.9rem;
  line-height: 1.5;
  background: #f8f9fa;
  padding: 0.75rem;
  border-radius: 8px;
  border-left: 3px solid #007bff;
}

/* 深色模式样式 */
@media (prefers-color-scheme: dark),
#app.dark-mode {
  .refund-query-modal .modal-content {
    background: #2d3748;
    border-color: #4a5568;
  }

  .refund-summary {
    background: linear-gradient(135deg, #4a5568, #2d3748);
    border-left-color: #63b3ed;
  }

  .refund-summary .summary-item {
    color: #e2e8f0;
  }

  .refund-summary .summary-item i {
    color: #63b3ed;
  }

  .refund-item-card {
    background: #4a5568;
    border-color: #718096;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  }

  .refund-item-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  }

  .refund-header {
    border-bottom-color: #718096;
  }

  .refund-date {
    color: #a0aec0;
  }

  .refund-amount .amount-label {
    color: #e2e8f0;
  }

  .refund-amount .amount-value {
    color: #63b3ed;
  }

  .refund-description {
    color: #a0aec0;
    background: #2d3748;
    border-left-color: #63b3ed;
  }

  .refund-status.pending {
    background-color: #744210;
    color: #fef3c7;
  }

  .refund-status.approved {
    background-color: #1e3a8a;
    color: #dbeafe;
  }

  .refund-status.rejected {
    background-color: #7f1d1d;
    color: #fecaca;
  }

  .refund-status.completed {
    background-color: #14532d;
    color: #dcfce7;
  }

  .empty-state .empty-icon {
    color: #718096;
  }

  .empty-state .empty-title {
    color: #e2e8f0;
  }

  .empty-state .empty-subtitle {
    color: #a0aec0;
  }
}

/* 移动端适配 */
@media (max-width: 768px) {
  .refund-query-modal .modal-content {
    max-width: 95vw;
    margin: 1rem;
  }

  .refund-list {
    padding: 1rem;
  }

  .refund-item-card {
    padding: 1rem;
  }

  .refund-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }

  .refund-amount {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }

  .refund-amount .amount-value {
    font-size: 1.25rem;
  }
}

.refund-dialog-footer {
  padding: 1.5rem;
  border-top: 1px solid #e9ecef;
  text-align: center;
  background: #f8f9fa;
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
}

.refund-dialog-footer .btn {
  min-width: 120px;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  border-radius: 8px;
  font-weight: 600;
  transition: all 0.3s ease;
}

.refund-dialog-footer .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(108, 117, 125, 0.3);
}

/* 深色模式底部按钮样式 */
@media (prefers-color-scheme: dark),
#app.dark-mode {
  .refund-dialog-footer {
    background: #2d3748;
    border-top-color: #4a5568;
  }
}

@media (max-width: 480px) {
  .refund-query-modal .modal-content {
    max-width: 100vw;
    margin: 0;
    border-radius: 0;
  }

  .refund-list {
    padding: 0.75rem;
  }

  .refund-summary {
    padding: 0.75rem;
  }

  .refund-dialog-footer {
    padding: 1rem;
  }

  .refund-dialog-footer .btn {
    width: 100%;
    min-width: auto;
  }
}
</style>